受保护的成员访问仅在未获取其地址时有效

Alb*_*ert 2 c++ inheritance

我有多重继承(类A是基类,B派生自AC派生自B)。 \nA有一个受保护的成员属性,我尝试在C.

\n\n

考虑这段代码:

\n\n
#include <iostream>\nusing namespace std;\n\nclass A {\nprotected:\n        int x;\npublic:\n        A() : x(42) {}\n};\n\nclass B : public A {\n};\n\nclass C : public B {\nprotected:\n        typedef B Precursor;\n\npublic:\n        void foo() {\n                cout << Precursor::x << endl;\n                cout << this->x << endl;\n        }\n\n        int get() {\n                return Precursor::x;\n        }\n\n        int* getPtr() {\n                // error: \xe2\x80\x98int A::x\xe2\x80\x99 is protected\n                // error: within this context\n                // error: cannot convert \xe2\x80\x98int A::*\xe2\x80\x99 to \xe2\x80\x98int*\xe2\x80\x99 in return\n                return &Precursor::x;\n                //return &this->x;  // this works\n        }\n};\n\n\nint main() {\n        C obj;\n        obj.foo();\n        cout << obj.get() << endl;\n        cout << obj.getPtr() << endl;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

C::foo()和 in 中C::get()Precursor::x可以访问x。\n但是,&Precursor::x不起作用。这是为什么?this->x并且&this->x总是有效。

\n\n

铿锵错误消息:

\n\n
cpp-inheritance.cpp:34:22: error: 'x' is a protected member of 'A'\n                return &Precursor::x;\n                                   ^\ncpp-inheritance.cpp:7:6: note: must name member using the type of the current context 'C'\n        int x;\n            ^\ncpp-inheritance.cpp:34:10: error: cannot initialize return object of type 'int *' with an\n      rvalue of type 'int A::*'\n                return &Precursor::x;\n                       ^~~~~~~~~~~~~\n2 errors generated.\n
Run Code Online (Sandbox Code Playgroud)\n

int*_*jay 5

当该&运算符用于 形式的限定名时C::m,其中C是一个类并且m是一个非静态成员,它返回一个指向类型成员的指针,C::*T其中Tism的类型。这是一种特殊情况,它会覆盖返回指向用作 操作数的表达式的指针的默认行为&

\n\n

要获取指向 C 是基类的指针C::m,您必须确保 的操作数&不是限定名称,例如使用&this->C::mor &(C::m)

\n\n

参考:C++14,5.3.1/3

\n\n
\n

如果操作数是一个 quali\xef\xac\x81ed-id,命名某个类型为 T 的类 C 的非静态成员 m,则结果的类型为 \xe2\x80\x9c,指向类型为 T\xe2\ 的类 C 的成员的指针x80\x9d 是指定 C::m 的纯右值

\n
\n