The following code fails to compile with this error with g++ and a similar error with clang.
main.cpp:16:19: error: 'QByteArray' is a private member of 'QByteArray' Container2(const QByteArray &ba); ^ main.cpp:3:18: note: constrained by private inheritance here class Container1:private QByteArray ^~~~~~~~~~~~~~~~~~ ../edge-clang/qt5/include/QtCore/qbytearray.h:167:21: note: member is declared here class Q_CORE_EXPORT QByteArray ^ main.cpp:18:30: error: 'QByteArray' is a private member of 'QByteArray' Container2::Container2(const QByteArray &ba):Container1(ba){} ^ main.cpp:3:18: note: constrained by private inheritance here class Container1:private QByteArray ^~~~~~~~~~~~~~~~~~ ../edge-clang/qt5/include/QtCore/qbytearray.h:167:21: note: member is declared here class Q_CORE_EXPORT QByteArray ^
I don't understand why this is not allowed for Container2 to inherit Container1 and initialize it through a public constructor, even though the inheritance of QByteArray is private.
#include <QByteArray> class Container1:private QByteArray { public: Container1() {} Container1(const QByteArray &ba); }; Container1::Container1(const QByteArray &ba):QByteArray(ba){} class Container2:public Container1 { public: Container2() {} Container2(const QByteArray &ba); }; Container2::Container2(const QByteArray &ba):Container1(ba){} int main(int argc,char *argv[]) { QByteArray ba; Container1 c1(ba); Container2 c2(ba); }
Private members of a base class can only be accessed by base member functions (not derived classes). So you have no rights not even a chance to do so :) Show activity on this post. Well, if you have access to base class, you can declare class B as friend class.
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass. A nested class has access to all the private members of its enclosing class—both fields and methods.
This is a great bug!
In the context of C
, "A
" means "the injected-class-name A
that I get from my base".
You could think of it as C::B::A
.
Of course, that base is inaccessible due to private inheritance:
class A {}; class B : private A { public: B() {} B(const A&) {} }; class C : public B { public: C(const A&) {} }; int main() { A a; B b(a); C c(a); } // main.cpp:11:13: error: 'class A A::A' is inaccessible within this context // C(const A&) {} // ^ // main.cpp:1:9: note: declared here // class A {}; // ^
You can fix this by calling it ::A
, taking a more indirect route to actually name the exact same type:
class A {}; class B : private A { public: B() {} B(const A&) {} }; class C : public B { public: C(const ::A&) {} }; int main() { A a; B b(a); C c(a); } // OK
As an aside, the exact same logic applies to private
ly inherited member variables:
int x = 1; class A { private: int x = 2; }; class B : A { public: B() { int y = x; } }; int main() { A a; B b(a); } // main.cpp: In constructor 'B::B()': // main.cpp:11:17: error: 'int A::x' is private within this context // B() { int y = x; }
It all does seem pretty stupid on the face of it, but there's probably a good reason.
In your case, then:
Container2(const ::QByteArray &ba);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With