, . BaseClass, Pimpl QExplicitlySharedDataPointer, BaseClassPrivate. DerivedClass, DerivedClassPrivate BaseClassPrivate.
BaseClassPrivate float baseParam DerivedClassPrivate float derivedParam.
:
BaseClass(BaseClassPrivate* p)
DerivedClassPrivate
clone() BaseClassPrivate, DerivedClassPrivate
, . "QExplicitlySharedDataPointer:: detach()" , QSharedData, . , QSharedData:: ref , ( ).
d- DerivedClass
dCasted().
, foo() BaseClassPrivate DerivedClassPrivate, baseParam derivedParam.
:
BaseClass.h
class BaseClass
{
public:
BaseClass() : d(new BaseClassPrivate()) {}
BaseClass(const BaseClass& other) : d(other.d) {}
BaseClass& operator =(const BaseClass& other) {d = other.d; return *this;}
virtual ~BaseClass() {}
float baseParam() const {return d->baseParam;}
void setBaseParam(float value) {
detach();
d->baseParam = value;
}
float foo() const {return d->foo();}
protected:
BaseClass(BaseClassPrivate* p) : d(p) {}
void detach() {
if (!d || d->ref == 1) return;
d = d->clone();
}
QExplicitlySharedDataPointer<BaseClassPrivate> d;
};
DerivedClass.h
class DerivedClass : public BaseClass
{
public:
DerivedClass() : BaseClass(new DerivedClassPrivate()) {}
float derivedParam() const {return dCasted()->derivedParam;}
void setDerivedParam(float value) {
detach();
dCasted()->derivedParam = value;
}
private:
DerivedClassPrivate* dCasted() const {return static_cast<DerivedDataPrivate*>(d.data());}
};
BaseClassPrivate.h
class BaseClassPrivate : public QSharedData
{
public:
BaseClassPrivate() : QSharedData(), baseParam(0.0) {}
BaseClassPrivate(const BaseClassPrivate& other) :
QSharedData(other), baseParam(other.baseParam) {}
virtual ~BaseClassPrivate() {}
float baseParam;
virtual float foo() const {return baseParam;}
virtual BaseClassPrivate* clone() const {
return new BaseClassPrivate(*this);
}
};
DerivedClassPrivate.h
class DerivedClassPrivate : public BaseClassPrivate
{
public:
DerivedClassPrivate() : BaseClassPrivate(), derivedParam(0.0) {}
DerivedClassPrivate(const DerivedClassPrivate& other) :
BaseClassPrivate(other), derivedParam(other.derivedParam) {}
float derivedParam;
virtual float foo() const {return derivedParam;}
virtual BaseClassPrivate* clone() const {
return new DerivedClassPrivate(*this);
}
};
, :
:
DerivedClass derived;
derived.setDerivedParam(1.0);
QCOMPARE(derived.foo(), 1.0); // proving that DerivedClassPrivate::foo() is called
DerivedClass BaseClass :
BaseClass baseCopy = derived;
QCOMPARE(baseCopy.foo(), 1.0);
BaseClass BaseClass , :
BaseClass bbCopy(baseCopy);
QCOMPARE(bbCopy.foo(), 1.0);
baseCopy.setBaseParam(2.0);
QCOMPARE(baseCopy.baseParam(), 2.0);
QCOMPARE(bbCopy.baseParam(), 1.0);
QCOMPARE(baseCopy.foo(), 1.0);
,