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

Jump to: navigation, search
(now...)
(no need to use d_func() in const functions)
Line 93: Line 93:
 
{
 
{
 
     Q_D(KFooBase);
 
     Q_D(KFooBase);
 +
 
     d->someInteger = i;
 
     d->someInteger = i;
 
}
 
}
Line 98: Line 99:
 
int KFooBase::someInteger() const
 
int KFooBase::someInteger() const
 
{
 
{
     // because of 'const' use d_func here instead of Q_D
+
     // in const functions add 'const' to the class name
     return d_func()->someInteger;
+
     Q_D(const KFooBase);
 +
 
 +
    return d->someInteger;
 
}
 
}
  
Line 123: Line 126:
 
{
 
{
 
     /* no need to delete the d-pointer! */
 
     /* no need to delete the d-pointer! */
 +
}
 +
 +
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
 
int KFooDerived::sumOfIntegers() const
 
{
 
{
     return d_func()->someInteger + d_func()->anotherInteger;
+
     // in const functions add 'const' to the class name
 +
    Q_D(const KFooDerived);
 +
 
 +
    return d->someInteger + d->anotherInteger;
 
}
 
}
 
</code>
 
</code>

Revision as of 00:35, 24 October 2008

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);
   void setSomeInteger(int i);
   int someInteger() const;

protected:

   KFooBasePrivate * const 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);
   int sumOfIntegers() const;

protected:

   KFooDerived(KFooDerivedPrivate &dd, QObject *parent);

private:

   friend class KFooDerivedPrivate;
   inline KFooDerivedPrivate *d_func()
   { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr); }
   inline const KFooDerivedPrivate *d_func() const
   { return reinterpret_cast<KFooDerivedPrivate *>(d_ptr); }

};

The header file, with Q_DECLARE_PRIVATE

class KFooBasePrivate; class KFooBase : public QObject { public:

   KFooBase(QObject *parent);
   void setSomeInteger(int i);
   int someInteger() const;

protected:

   KFooBasePrivate * const d_ptr;
   KFooBase(KFooBasePrivate &dd, QObject *parent);

private:

   Q_DECLARE_PRIVATE(KFooBase)

};

class KFooDerivedPrivate; class KFooDerived : public KFooBase { public:

   KFooDerived(QObject *parent);
   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)

{ }

KFooBase::~KFooBase() {

   delete d_ptr;

}

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)

{ }

KFooDerived::~KFooDerived() {

   /* no need to delete the d-pointer! */

}

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