Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 受保护的成员访问仅在未获取其地址时有效_C++_Inheritance - Fatal编程技术网

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

C++ 受保护的成员访问仅在未获取其地址时有效,c++,inheritance,C++,Inheritance,我有多重继承(类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:

我有多重继承(类
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;
}

因为preducer::x不是类的静态成员,所以无法获取其地址。您需要声明实例,并获取实例的地址成员。这就是此->x工作的原因: 1.C继承B它的成员x继承自B 及
2.这指定了C的当前实例。

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

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

参考:C++14,5.3.1/3

如果操作数是一个限定id,用类型T命名某类C的非静态成员m,则结果的类型为“指向类型T的C类成员的指针”,并且是一个指定C::m的PR值


无法在ideone上重现第一个错误(访问
C
中的
x
):您确定这是失败的代码吗?
是否最后一个错误生成指向成员的指针。您需要显式地指定实例:
&this->preducer::x
&(preducer::x)
也应该可以工作。看起来这是C++语法中的又一种形式。这不是多层次继承而不是多继承。这解释了为什么<代码> cUT这与静态成员无关。毕竟,尽管
x
不是静态的,但访问
preducer::x
仍然有效——在本例中,这意味着“从
preducer
继承的x成员变量”。
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.