Results 1 to 7 of 7

Thread: Q_D: d-pointer private in this context?

  1. #1
    Join Date
    Oct 2011
    Posts
    35
    Thanked 9 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Q_D: d-pointer private in this context?

    Hi,

    I am trying to implement the D-pointer pattern for some of my classes. I've followed the tutorials http://zchydem.enume.net/2010/01/19/...nd-d-pointers/ and http://techbase.kde.org/Policies/Lib...ointer_Example but whenever I access a private member of my d-pointer, a compiler error results stating that the member is private in the given context. Q_DECLARE_PRIVATE is supposed to make my XYZPrivate class a friend of my XYZ class, so why is there a problem accessing its private data members?

    Here's the relevant code:

    Employer.h:
    Qt Code:
    1. class EmployerPrivate;
    2.  
    3. class Employer : public Loggable
    4. {
    5. public:
    6. Employer(QString name, QString market);
    7. ~Employer();
    8.  
    9. QList<Position> findJobs() const;
    10. QString toString() const;
    11. bool hire(Person& newHire, Position pos);
    12.  
    13. protected:
    14. const QScopedPointer<EmployerPrivate> d_ptr;
    15.  
    16. private:
    17. Q_DECLARE_PRIVATE(Employer)
    18. };
    To copy to clipboard, switch view to plain text mode 

    Employer.cpp:
    Qt Code:
    1. Employer::Employer(QString name, QString market) :
    2. d_ptr(new EmployerPrivate(name, market))
    3. {
    4. }
    5.  
    6. Employer::~Employer()
    7. {
    8. }
    9.  
    10. QList<Position> Employer::findJobs() const
    11. {
    12. Q_D(const Employer);
    13. return d->m_positions; // Compiler error: m_positions private within context
    14. }
    15.  
    16. QString Employer::toString() const
    17. {
    18. Q_D(const Employer);
    19. return QString("***Employer information***\nName: %1\nMarket: %2").arg(d->m_name).arg(d->m_market); // Compiler error
    20. }
    To copy to clipboard, switch view to plain text mode 

    EmployerPrivate.h:
    Qt Code:
    1. class EmployerPrivate
    2. {
    3. public:
    4. EmployerPrivate(QString name, QString market);
    5.  
    6. private:
    7. QList<Position> m_positions;
    8. QString m_name;
    9. QString m_market;
    10. };
    To copy to clipboard, switch view to plain text mode 

    EmployerPrivate.cpp:
    Qt Code:
    1. EmployerPrivate::EmployerPrivate(QString name, QString market) :
    2. m_name(name),
    3. m_market(market)
    4. {
    5. }
    To copy to clipboard, switch view to plain text mode 

    I've tried making both classes derive from QObject and added the Q_OBJECT macro just in case (even though, from my understanding, these aren't needed), but that also did not work.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Q_D: d-pointer private in this context?

    Q_DECLARE_PRIVATE cannot possibly make Employer a friend of EmployerPrivate: to do that it would have to be inside the EmployerPrivate class. It does make EmployerPrivate a friend of Employer, i.e. the EmployerPrivate class can access the Employer private members.

    Q_DECLARE_PUBLIC inside the private class has the effect you are seeking. However, you'll find the ClassPrivate class contents are public in the examples you linked to.

  3. #3
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Q_D: d-pointer private in this context?

    Well the error message seems clear to me! m_positions is private. Solution: make it public. Thus you have to delete private: from the class EmployerPrivate. As most private classes only have public members.


    EDIT: refresh before posting can help...

  4. #4
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Q_D: d-pointer private in this context?

    Pattern looks like this:
    Qt Code:
    1. // public Header file for SomeLibBaseClass
    2. class SomeLibBaseClassPrivate;
    3.  
    4. class SomeLibBaseClass : public LibExternalClass {
    5. ...
    6. protected:
    7. SomeLibBaseClassPrivate *d_ptr; // or QScopedPointer<SomeLibBaseClassPrivate>
    8. SomeLibBaseClass(SomeLibBaseClassPrivate &dd, other args); // needed for subclassing inside library
    9.  
    10. private:
    11. Q_DISABLE_COPY(SomeLibBaseClass)
    12. Q_DECLARE_PRIVATE_D(d_ptr, SomeLibBaseClass)
    13. }
    14.  
    15. // -------------------------------------------------
    16. // private header file for SomeLibBaseClass
    17.  
    18. class SomeLibBaseClass;
    19.  
    20. class SomeLibBaseClassPrivate {
    21.  
    22. Q_DECLARE_PUBLIC(SomeLibBaseClass)
    23.  
    24. public:
    25. SomeLibBaseClassPrivate();
    26.  
    27. virtual ~SomeLibBaseClassPrivate(); // !!! OBLIGATORY virtual destructor. HAVE to do it if you want avoid strange hard to locate errors
    28.  
    29. // in general private class shouldn't have virtual methods (except destructor which is obligatory)
    30. // It is never a Q_Object, it doesn't have meta data
    31.  
    32. SomeLibBaseClass *q_ptr;
    33. }
    34.  
    35. // -------------------------------------------------
    36. // public Header file for SomeLibSubClass
    37.  
    38. class SomeLibSubClassPrivate;
    39.  
    40. class SomeLibSubClass : public SomeLibBaseClass {
    41.  
    42. protected:
    43. SomeLibSubClass(SomeLibSubClassPrivate &dd, otherArgs); // needed for subclassing inside lib
    44.  
    45. private:
    46. Q_DECLARE_PRIVATE_D(d_ptr, SomeLibSubClass)
    47. // no new d_pointer, it is inherited
    48. };
    49.  
    50. // -------------------------------------------------
    51. // private header file for SomeLibSubClass
    52. #include "somelibbaseclass.h"
    53. class SomeLibSubClass;
    54.  
    55. class SomeLibSubClassPrivate : public SomeLibBaseClassPrivate {
    56.  
    57. Q_DECLARE_PUBLIC(SomeLibSubClass)
    58.  
    59. public:
    60. SomeLibSubClassPrivate();
    61.  
    62. ~SomeLibBaseClassPrivate(); // here is optional
    63.  
    64. // q pointer is not needed, it is inharited
    65. }
    To copy to clipboard, switch view to plain text mode 
    macro Q_DECLARE_PRIVATE_D and Q_DECLARE_PUBLIC (you didn't use that macro that is why you have a problem, don't forget about q_pointer) provides friendship between public and private class. You should use both.

    It would be the best if you take a look how Qt is written. There you have all cases of d_pointer usage.
    For example objects with implicit data sharing (like QString, QByteArray, QVector, QList) have a different set of roles.

  5. #5
    Join Date
    Oct 2011
    Posts
    35
    Thanked 9 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Q_D: d-pointer private in this context?

    Thank you MarekR22, that works great. I'm wondering though: is q_pointer required? I thought that was only necessary if the private class needed to access the private members of the public class. Do I still need to include q_pointer if my private class does not need to access the public class' private members (since I get a compiler error when I take out the q_pointer, it seems like it does need it; I'd just like to understand better why it is needed)?

    Thanks!

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Q_D: d-pointer private in this context?

    The public class will generally have no private members other than the d pointer.

    The q pointer is primarily used to access the signals of the publicly visible class, which are declared protected in the public class, from the private impl class. This is a convenience.. otherwise the impl class would have to emit signals, that were connected to trigger the public class signal of the same function.

  7. #7
    Join Date
    Oct 2011
    Posts
    35
    Thanked 9 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Q_D: d-pointer private in this context?

    Thanks for the explanation Chris, that makes a lot of sense.

Similar Threads

  1. QTransform method is private within this context error
    By planetLars in forum Qt Programming
    Replies: 2
    Last Post: 14th February 2012, 15:37
  2. Replies: 4
    Last Post: 4th January 2011, 12:07
  3. Replies: 1
    Last Post: 4th December 2010, 17:20
  4. private slots ??
    By salmanmanekia in forum Qt Programming
    Replies: 7
    Last Post: 6th August 2008, 14:00
  5. Why does Qt use Private classes?
    By hyling in forum Qt Programming
    Replies: 2
    Last Post: 12th December 2006, 22:11

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.