Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.
-
Hey
I'm trying to learn how Qt is build so it has a private&public classes/headers that are able to inherit private-from-private / public-from-public and "work".
I've gone over https://community.kde.org/Policies/Library_Code_Policy and https://techbase.kde.org/Policies/Library_Code_Policy/Shared_D-Pointer_Example
But as far as I can tell... that is a little "outdated" and I'm not sure what is the current way of doing it.
What I understand is that I have to declare Q_DECLAER_PRIVATE(myClassName) in public header and in private header declare Q_DECLARE_PUBLIC(myClassName)
So that "appear" to work, but then when I try to compile I get >
error C2065: 'q_ptr': undeclared identifier
in my private header.I can also see Q_DECLARE_PRIVATE_D but I've no idea what this one do o.o.
Is that meant to be used by inherited classes? So say if I do :class myGraphicsItem : public QGraphicsItem { Q_DECLARE_PRIVATE_D(QGraphicsItem ::d_ptr.data(), myGraphicsItem ) }
In which case, if I inherit from more than 1 class say >
class myGraphicsItem : public QObject, public QGraphicsItem{ Q_DECLARE_PRIVATE_D(QObject::d_ptr.data(), myGraphicsItem ) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), myGraphicsItem ) }
is this correct ?
How can I learn about this black magic O_O ?
TIA
Regards
Dariusz -
@Dariusz Check this: https://wiki.qt.io/D-Pointer
-
@jsulm thats awesome thank you!
But still stuck :- D
I made an example project > https://github.com/Dariusz1989/dPointerLearn
This currently gives me >error C2143: syntax error: missing ';' before '*' error C7524: 'inline' specifier cannot appear on a block-scope declaration or non-static data member error C4430: missing type specifier - int assumed. Note: C++ does not support default-int error C2334: unexpected token(s) preceding '{'; skipping apparent function body error C2327: 'extra::controllers::inheritedPrivate::inherited': is not a type name, static, or enumerator
I'm lost :- (
What do I do ? -
@JonB said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
@Dariusz
You should state which file and which line number the first error occurs on.ops, my bad >
inherited_p.h(18): error C2143: syntax error: missing ';' before '*' inherited_p.h(18): error C7524: 'inline' specifier cannot appear on a block-scope declaration or non-static data member inherited_p.h(18): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int inherited_p.h(18): error C2334: unexpected token(s) preceding '{'; skipping apparent function body inherited_p.h(20): error C2327: 'extra::controllers::inheritedPrivate::inherited': is not a type name, static, or enumerator
All of it point to
Q_DECLARE_PUBLIC(inherited);
and
inheritedPrivate(inherited *item);
TIA!
-
@Dariusz said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
Q_DECLARE_PUBLIC(inherited);
Remove ;
-
@jsulm said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
@Dariusz said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
Q_DECLARE_PUBLIC(inherited);
Remove ;
Hmmm, now why? As far as I can tell QWidget_p.h has it declared?
also, it appears to "work" I've pushed git for the public.
Ok I got the Q_DECLARE_PUBLIC working as well, looks like I had circular include there.
-
@jsulm said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
Remove ;
OOI, why?! https://code.woboq.org/qt5/qtbase/src/corelib/global/qglobal.h.html#_M/Q_DECLARE_PUBLIC
#define Q_DECLARE_PUBLIC(Class) \ inline Class* q_func() { return static_cast<Class *>(q_ptr); } \ inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \ friend class Class;
So it gets an extra
;
at the end, so what? :) -
@JonB said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
@jsulm said in Learning & Undertanding Q_DECLARE_PRIVATE/PUBLIC macros/sdk.:
Remove ;
OOI, why?! https://code.woboq.org/qt5/qtbase/src/corelib/global/qglobal.h.html#_M/Q_DECLARE_PUBLIC
#define Q_DECLARE_PUBLIC(Class) \ inline Class* q_func() { return static_cast<Class *>(q_ptr); } \ inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \ friend class Class;
So it gets an extra
;
at the end, so what? :)oh you said to remove
;
uhh ok, my bad :DOk so ! Multiple inheritance!
As far as I can tell when it comes to Q_DECLARE_PRIVATE_D I have to specify which base -private class I want to inherit. As it appears that I can only grab one.
Q_DECLARE_PRIVATE_D(QObject::d_ptr.data(), inherited); //Q_DECLARE_PRIVATE_D(core::base::baseClass::d_ptr, inherited); // I can only inherit 1 base class?
With the code above, I can access QObject members, but core::base::baseClass are invalid. Where as if I swap the // around, and use baseClass as target, then I can access baseClass members, but QObject are invalid then.
I take in this case... I would have to make a "new" macro, something like
Q_DECLARE_PRIVATE2_D
&Q_DECLARE_PRIVATE3_D
&Q_DECLARE_PRIVATE4_D
etc etc & have multi base ptr storage as well likebaseClassPrivate *d_ptr; baseClassPrivate *d_ptr2; baseClassPrivate *d_ptr3; baseClassPrivate *d_ptr4;
At which point I should look in to map logic and more complex macro. As well as my
inherited(inheritedPrivate &d);
would need to be more likeinherited(QMap<QString,inheritedPrivate >&d);
or something like that.So that when I do Q_D / Q_Q I should be able to specify which baseClass source I want to use ?
I take Qt is fairly "strict" when it comes to sdk/d-pointers and thus there are no multi-inheritances issues. However if I want to inherit form both Qt & my own base class then I need to solve it ?
TIA
-
Welp I hit bu bu.
When I doQ_D(const myCLass) d->doStuff();
I get
Exception: Exception 0xc0000005 encountered at address 0x7ff62fe17f70: User-mode data execution prevention (DEP) violation at location 0x7ff62fe17f70
It happens on d->doStuff();
but if I do
auto d = static_cast<myClassPrivate*>(d_ptr); d->doStuff();
then it all works :D SHISH!
-
If doStuff() is not const, then don't declare
d
pointer as const:Q_D(myClass) // NO "const" here! d->doStuff();