派生类地址赋值基类指针编译报错:访问说明符作用解析
正常编译案例
#include <iostream> #include <sstream> using namespace std; class A{ public: A(){ cout << "A" << endl; } virtual void foo() { cout << "A' foo" << endl; } }; class B{ public: B(){ cout << "B" << endl; } virtual void foo() { cout << "B' foo" << endl; } }; class C{ public: C(){ cout << "C" << endl; } virtual void foo() { cout << "C' foo" << endl; } }; class D : public B,A,C{ public: D(){ cout << "D" << endl; } void foo() { cout << "D' foo" << endl; A::foo(); } }; int main() { class B*ptr = new D; return 0; }
编译报错案例
A是D的基类,但为何编译器不允许将派生类地址赋值给基类指针?
int main() { class A*ptr = new D; return 0; }
输出:error: ‘A’ is an inaccessible base of ‘D’
始终正常编译案例
为每个基类指定访问说明符后即可正常编译:
#include <iostream> #include <sstream> using namespace std; class A{ public: A(){ cout << "A" << endl; } virtual void foo() { cout << "A' foo" << endl; } }; class B{ public: B(){ cout << "B" << endl; } virtual void foo() { cout << "B' foo" << endl; } }; class C{ public: C(){ cout << "C" << endl; } virtual void foo() { cout << "C' foo" << endl; } }; class D : public B, public A, public C{ public: D(){ cout << "D" << endl; } void foo() { cout << "D' foo" << endl; A::foo(); } }; int main() { class A*ptr = new D; return 0; }
多继承场景下访问说明符的工作机制
在C++中,用class关键字定义派生类时,如果没有显式指定基类的访问说明符,编译器会默认使用private继承(如果是struct定义的类,默认则是public继承)。
结合你的案例拆解:
- 第一个场景里
class D : public B,A,C,B被显式声明为public继承,而A和C没有指定访问说明符,所以默认是private继承:public继承的B:外部代码可以把D*隐式转换为B*,因为B是D的可访问基类,这也是第一个案例能正常编译的原因。private继承的A、C:基类的继承关系对外部代码隐藏,外部无法将D*转换为A*或C*,这就是第二个案例报错“A是不可访问基类”的核心原因。
- 第三个场景里
class D : public B, public A, public C,所有基类都显式指定了public继承:- 此时
A、B、C都是D的可访问基类,外部代码可以自由将D*转换为任意基类指针,因此编译正常。
- 此时
额外补充几个关键细节:
- 访问说明符本质控制的是基类在派生类中的可见性,以及外部代码对基类接口的访问权限:
public继承:基类的public/protected成员在派生类中保留原有访问级别,外部代码可通过派生类对象访问基类public成员,且支持隐式类型转换。private继承:基类的public/protected成员在派生类中变为private,外部代码无法访问基类任何成员,也不允许隐式转换为基类指针/引用,但派生类内部仍然可以访问基类的public/protected成员(比如第一个案例中D::foo()能调用A::foo())。protected继承:基类的public/protected成员在派生类中变为protected,外部代码无法访问,但派生类的子类可以访问基类的protected成员。
内容的提问来源于stack exchange,提问作者Hardik
相关产品推荐
相关产品推荐

