Difference between revisions of "Policies/Library Code Policy/Shared D-Pointer Example"

Jump to: navigation, search
(Move the example here from the Library_Code_Policy page)
 
(s/QScopePointer/QScopedPointer/ (and few miner fixes))
(12 intermediate revisions by 6 users not shown)
Line 1: Line 1:
The following example illustrates the [[Policies/Library_Code_Policy#Shared D-Pointer|shared d-pointer]] concept. The class presented here derives from QObject to illustrate parameter-passing in the constructor; it is not necessary to be like that in your code.
+
The following example illustrates the [[Policies/Library_Code_Policy#Shared D-Pointers|shared d-pointer]] concept. The class presented here derives from QObject to illustrate parameter-passing in the constructor; it is not necessary to be like that in your code.
  
 
== The header file, without Q_DECLARE_PRIVATE ==
 
== The header file, without Q_DECLARE_PRIVATE ==
<code cppqt>
+
<source lang="cpp-qt">
 
class KFooBasePrivate;
 
class KFooBasePrivate;
 
class KFooBase : public QObject
 
class KFooBase : public QObject
Line 8: Line 8:
 
public:
 
public:
 
     KFooBase(QObject *parent);
 
     KFooBase(QObject *parent);
 +
    ~KFooBase();
 +
    void setSomeInteger(int i);
 
     int someInteger() const;
 
     int someInteger() const;
 
protected:
 
protected:
     KFooBasePrivate * const d_ptr;
+
     const QScopedPointer<KFooBasePrivate> d_ptr;
 
     KFooBase(KFooBasePrivate &dd, QObject *parent);
 
     KFooBase(KFooBasePrivate &dd, QObject *parent);
 
private:
 
private:
Line 23: Line 25:
 
public:
 
public:
 
     KFooDerived(QObject *parent);
 
     KFooDerived(QObject *parent);
 +
    void setAnotherInteger(int i);
 +
    int anotherInteger() const;
 
     int sumOfIntegers() const;
 
     int sumOfIntegers() const;
 
protected:
 
protected:
Line 29: Line 33:
 
     friend class KFooDerivedPrivate;
 
     friend class KFooDerivedPrivate;
 
     inline KFooDerivedPrivate *d_func()
 
     inline KFooDerivedPrivate *d_func()
     { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr); }
+
     { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr.data()); }
 
     inline const KFooDerivedPrivate *d_func() const
 
     inline const KFooDerivedPrivate *d_func() const
     { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr); }
+
     { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr.data()); }
 
};
 
};
</code>
+
</source>
  
 
== The header file, with Q_DECLARE_PRIVATE ==
 
== The header file, with Q_DECLARE_PRIVATE ==
<code cppqt>
+
<source lang="cpp-qt">
 
class KFooBasePrivate;
 
class KFooBasePrivate;
 
class KFooBase : public QObject
 
class KFooBase : public QObject
Line 42: Line 46:
 
public:
 
public:
 
     KFooBase(QObject *parent);
 
     KFooBase(QObject *parent);
 +
    ~KFooBase();
 +
    void setSomeInteger(int i);
 
     int someInteger() const;
 
     int someInteger() const;
 
protected:
 
protected:
     KFooBasePrivate * const d_ptr;
+
     const QScopedPointer<KFooBasePrivate> d_ptr;
 
     KFooBase(KFooBasePrivate &dd, QObject *parent);
 
     KFooBase(KFooBasePrivate &dd, QObject *parent);
 
private:
 
private:
Line 55: Line 61:
 
public:
 
public:
 
     KFooDerived(QObject *parent);
 
     KFooDerived(QObject *parent);
 +
    void setAnotherInteger(int i);
 +
    int anotherInteger() const;
 
     int sumOfIntegers() const;
 
     int sumOfIntegers() const;
 
protected:
 
protected:
Line 61: Line 69:
 
     Q_DECLARE_PRIVATE(KFooDerived)
 
     Q_DECLARE_PRIVATE(KFooDerived)
 
};
 
};
</code>
+
</source>
  
 
== The .cpp file ==
 
== The .cpp file ==
<code cppqt>
+
<source lang="cpp-qt">
 
/*** KFooBase ***/
 
/*** KFooBase ***/
 
class KFooBasePrivate
 
class KFooBasePrivate
Line 83: Line 91:
 
}
 
}
  
 +
// The destructor must be in the .cpp file, even if empty
 
KFooBase::~KFooBase()
 
KFooBase::~KFooBase()
 
{
 
{
    delete d_ptr;
 
 
}
 
}
  
int KFooBase::someInteger() const
+
void KFooBase::setSomeInteger(int i)
 
{
 
{
 
     Q_D(KFooBase);
 
     Q_D(KFooBase);
 +
 +
    d->someInteger = i;
 +
}
 +
 +
int KFooBase::someInteger() const
 +
{
 +
    // in const functions add 'const' to the class name
 +
    Q_D(const KFooBase);
 +
 
     return d->someInteger;
 
     return d->someInteger;
 
}
 
}
Line 112: Line 129:
 
}
 
}
  
KFooDerived::~KFooDerived()
+
void KFooDerived::setAnotherInteger(int i)
 
{
 
{
     /* no need to delete the d-pointer! */
+
    Q_D(KFooDerived);
 +
 
 +
    d->anotherInteger = i;
 +
}
 +
 
 +
int KFooDerived::anotherInteger() const
 +
{
 +
     // in const functions add 'const' to the class name
 +
    Q_D(const KFooDerived);
 +
 
 +
    return d->anotherInteger;
 
}
 
}
  
 
int KFooDerived::sumOfIntegers() const
 
int KFooDerived::sumOfIntegers() const
 
{
 
{
     Q_D(KFooDerived);
+
    // in const functions add 'const' to the class name
 +
     Q_D(const KFooDerived);
 +
 
 
     return d->someInteger + d->anotherInteger;
 
     return d->someInteger + d->anotherInteger;
 
}
 
}
</code>
+
</source>

Revision as of 14:00, 17 February 2012

The following example illustrates the shared d-pointer concept. The class presented here derives from QObject to illustrate parameter-passing in the constructor; it is not necessary to be like that in your code.

The header file, without Q_DECLARE_PRIVATE

class KFooBasePrivate;
class KFooBase : public QObject
{
public:
    KFooBase(QObject *parent);
    ~KFooBase();
    void setSomeInteger(int i);
    int someInteger() const;
protected:
    const QScopedPointer<KFooBasePrivate> d_ptr;
    KFooBase(KFooBasePrivate &dd, QObject *parent);
private:
    friend class KFooBasePrivate;
    inline KFooBasePrivate *d_func() { return d_ptr; }
    inline const KFooBasePrivate *d_func() const { return d_ptr; }
};
 
class KFooDerivedPrivate;
class KFooDerived : public KFooBase
{
public:
    KFooDerived(QObject *parent);
    void setAnotherInteger(int i);
    int anotherInteger() const;
    int sumOfIntegers() const;
protected:
    KFooDerived(KFooDerivedPrivate &dd, QObject *parent);
private:
    friend class KFooDerivedPrivate;
    inline KFooDerivedPrivate *d_func()
    { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr.data()); }
    inline const KFooDerivedPrivate *d_func() const
    { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr.data()); }
};

The header file, with Q_DECLARE_PRIVATE

class KFooBasePrivate;
class KFooBase : public QObject
{
public:
    KFooBase(QObject *parent);
    ~KFooBase();
    void setSomeInteger(int i);
    int someInteger() const;
protected:
    const QScopedPointer<KFooBasePrivate> d_ptr;
    KFooBase(KFooBasePrivate &dd, QObject *parent);
private:
    Q_DECLARE_PRIVATE(KFooBase)
};
 
class KFooDerivedPrivate;
class KFooDerived : public KFooBase
{
public:
    KFooDerived(QObject *parent);
    void setAnotherInteger(int i);
    int anotherInteger() const;
    int sumOfIntegers() const;
protected:
    KFooDerived(KFooDerivedPrivate &dd, QObject *parent);
private:
    Q_DECLARE_PRIVATE(KFooDerived)
};

The .cpp file

/*** KFooBase ***/
class KFooBasePrivate
{
public:
    virtual ~KFooBasePrivate() { }
    int someInteger;
};
 
KFooBase::KFooBase(QObject *parent) 
    : QObject(parent), d_ptr(new KFooBasePrivate)
{
}
 
KFooBase::KFooBase(KFooBasePrivate &dd, QObject *parent)
    : QObject(parent), d_ptr(&dd)
{
}
 
// The destructor must be in the .cpp file, even if empty
KFooBase::~KFooBase()
{
}
 
void KFooBase::setSomeInteger(int i)
{
    Q_D(KFooBase);
 
    d->someInteger = i;
}
 
int KFooBase::someInteger() const
{
    // in const functions add 'const' to the class name
    Q_D(const KFooBase);
 
    return d->someInteger;
}
 
/*** KFooDerived ***/
 
class KFooDerivedPrivate: public KFooBasePrivate
{
public:
    int anotherInteger;
};
 
KFooDerived::KFooDerived(QObject *parent)
    : KFooBase(*new KFooDerivedPrivate, parent)
{
}
 
KFooDerived::KFooDerived(KFooDerivedPrivate &dd, QObject *parent)
    : KFooBase(dd, parent)
{
}
 
void KFooDerived::setAnotherInteger(int i)
{
    Q_D(KFooDerived);
 
    d->anotherInteger = i;
}
 
int KFooDerived::anotherInteger() const
{
    // in const functions add 'const' to the class name
    Q_D(const KFooDerived);
 
    return d->anotherInteger;
}
 
int KFooDerived::sumOfIntegers() const
{
    // in const functions add 'const' to the class name
    Q_D(const KFooDerived);
 
    return d->someInteger + d->anotherInteger;
}

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal