PDA

View Full Version : Inheritance and QExplicitlySharedDataPointer



tbcpp
22nd April 2010, 21:38
What is the best way to use QExplicitlySharedDataPointer and inherited classes. I would like when the BaseClass exits on it's own to have a my d pointer be QExplicitlySharedDataPointer <BaseClassPrivate> and when I have a Derived class on top of this base class I'd like to have d be a QExplicitlySharedDataPointer <DerivedClassPrivate>.

I tried making DerivedClassPrivate inherit from BaseClassPrivate, and then make the d pointer protected and re-define the d-pointer in my derived class, but it seems now that I have two copies of the d-pointer both local to the class they are defined in... which is not what I want.

wysota
22nd April 2010, 21:56
There are actually two ways of doing this. What I usually do is that I don't use QExplicitlySharedDataPointer but instead I implement this functionality myself using QAtomic* classes. Another approach is to implement the QExplicitlySharedDataPointer::clone() for your data type. It makes it possible to decide about the type of the pimpl object based on the public component. Then you can declare the shared pointer in the base class and assign proper pimpls in subclasses. It still requires you to do the cast in subclasses when you wish to access members declared in the subclass.

Algirdasss
28th May 2010, 09:18
I also had same question, but my aim was to use standard QT classes like QSharedData and QExplicitlySharedDataPointer ... solution I came upon is (small sample):


class BaseClass{
public:
BaseClass(){
_d = new BaseData();
}

protected:
BaseData(BaseData *data){
_d = data;
}

QExplicitlySharedDataPointer<BaseData> _d;
};

class DerivedClass : public BaseClass{
public:
DerivedClass() : BaseClass(new DerivedData()){
_d = static_cast<DerivedData*>(BaseClass::_d.data());
}

// Construtor for upcasting. This must be implemented if we want to do upcasting with variables placed in stack.
DerivedClass(BaseClass &bs) : BaseClass(bs){
_d = static_cast<DerivedData*>(BaseClass::_d.data());
}

protected:
QExplicitlySharedDataPointer<DerivedData> _d;
};

main(){
DerivedClass dc;
BaseClass bs = dc;
DerivedClass dc2 = bs;
DerivedClass dc3 = static_cast<DerivedClass>(bs); // Same result as above

// After all these operations we have only single instance of shared data
}


The result is that both base class and derived class has separate explicitly shared pointers named "_d". But its impossible to avoid this!!! The best you can achieve here is variable overloading. But this pointer points to the same data class instance!!! If somebody will find better solution, it would be interesting to hear it.

P.S. after posting this I just thought that it is also possible not to define variable "_d" in derived class but use BaseClass variable instead. Just in this case well have to do more casting operations when accesing values.