我有多重继承(类A
是基类,B
派生自A
,C
派生自B
)。
A
有一个受保护的成员属性,我尝试在C
中以不同的方式访问该属性。
考虑以下代码:
#include <iostream>
using namespace std;
class A {
protected:
int x;
public:
A() : x(42) {}
};
class B : public A {
};
class C : public B {
protected:
typedef B Precursor;
public:
void foo() {
cout << Precursor::x << endl;
cout << this->x << endl;
}
int get() {
return Precursor::x;
}
int* getPtr() {
// error: ‘int A::x’ is protected
// error: within this context
// error: cannot convert ‘int A::*’ to ‘int*’ in return
return &Precursor::x;
//return &this->x; // this works
}
};
int main() {
C obj;
obj.foo();
cout << obj.get() << endl;
cout << obj.getPtr() << endl;
}
在C::foo()
和C::get()
中,Precursor::x
可以访问x
。
但是,&Precursor::x
不起作用。这是为什么? this->x
和&this->x
始终有效。
Clang错误消息:
cpp-inheritance.cpp:34:22: error: 'x' is a protected member of 'A'
return &Precursor::x;
^
cpp-inheritance.cpp:7:6: note: must name member using the type of the current context 'C'
int x;
^
cpp-inheritance.cpp:34:10: error: cannot initialize return object of type 'int *' with an
rvalue of type 'int A::*'
return &Precursor::x;
^~~~~~~~~~~~~
2 errors generated.
答案 0 :(得分:4)
如果&
运算符用于C::m
表单的限定名称,其中C
是一个类而m
是非静态成员,则返回指向C::*T
类型的成员指针,其中T
是m
的类型。这是一种特殊情况,它会覆盖返回指向用作&
操作数的表达式的指针的默认行为。
要获取指向C::m
的指针,其中C是基类,您必须使其&
的操作数不是限定名,例如使用&this->C::m
或&(C::m)
。
参考:C ++ 14,5.3.1 / 3
如果操作数是一个qualic fi-id,命名一个类型为T的某个类C的非静态成员m,则结果类型为“指向类型为C的C类成员的指针”,并且是一个指定C :: m的prvalue
答案 1 :(得分:0)
因为Precursor :: x不是类的静态成员,所以无法获取其地址。您需要声明实例,并获取实例的地址成员。这就是为什么这个&gt; x有效: 1. C继承B它具有继承自B的成员x 和 2.这指定C的当前实例。