如何直接访问基类的protected成员?(附编译失败代码示例)
基类protected成员访问问题:在Base::a必须为protected的前提下如何访问
先帮你理清编译失败的核心原因:你是在main这个全局函数里直接写x = b.a,但a是Base的protected成员——C++里protected成员的访问规则是只有基类本身、基类的友元,以及派生类的成员函数/友元才能访问,main不属于任何一类,所以编译器会报错。你之前误解成“派生类无法访问Base实例的成员”,其实派生类的成员函数是可以访问自己继承来的a的,只是外部函数不行。
下面给你几种符合要求的解决方案,都保证Base::a还是protected:
方案1:给Derived加个getter方法(最推荐,符合封装)
这是最常规的做法,通过派生类提供的接口来访问内部的protected成员:
#include <iostream> using namespace std; class Base { protected : int a; public : Base() {}; Base(int x) :a(x) {}; }; class Derived : public Base { public: Derived(int x) : Base(x) {}; // 新增getter,派生类成员可以直接访问自己的a int getA() const { return a; } }; int main() { Derived b(11); int x = b.getA(); // 通过接口访问 cout << x << endl; return 0; }
方案2:把main声明为Derived的友元
如果你不想加getter,也可以把main设为Derived的友元,这样它就能直接访问Derived对象的protected成员(包括继承来的a):
#include <iostream> using namespace std; class Base { protected : int a; public : Base() {}; Base(int x) :a(x) {}; }; class Derived : public Base { public: Derived(int x) : Base(x) {}; friend int main(); // 声明main为友元 }; int main() { Derived b(11); int x = b.a; // 现在能直接访问了 cout << x << endl; return 0; }
方案3:用Derived的静态成员函数访问任意Derived对象的a
如果需要访问其他Derived实例的a,可以写个静态成员函数来做中转:
#include <iostream> using namespace std; class Base { protected : int a; public : Base() {}; Base(int x) :a(x) {}; }; class Derived : public Base { public: Derived(int x) : Base(x) {}; static int getA(const Derived& obj) { return obj.a; // 派生类可以访问同类型对象的基类protected成员 } }; int main() { Derived b(11); int x = Derived::getA(b); cout << x << endl; return 0; }
另外说一下你之前尝试的构造函数写法:Derived() {Base(static_cast<Derived*>(this)->a);}; 这种写法是错误的,首先你不能在构造函数体内直接调用基类构造函数(只能在初始化列表里),其次你混淆了访问权限的适用场景,这个思路解决不了问题哦。
内容的提问来源于stack exchange,提问作者Stef1611
相关产品推荐
相关产品推荐

