派生类访问基类成员报错的根本原因是继承方式影响成员可见性:public继承保持原访问级,protected继承将非private成员转为protected,private继承全转为private。

派生类里访问基类成员为什么报错?
根本原因不是语法写错了,而是继承方式决定了基类成员在派生类中的可见性。比如基类有个 protected 成员,在 public 继承下它在派生类内部可访问;但换成 private 继承,它就变成派生类的私有成员,外部不可见——连派生类自己的成员函数都可能被编译器拦住。
-
public继承:基类的public成员在派生类中仍是public,protected保持protected,private始终不可见 -
protected继承:基类所有非private成员在派生类中都变成protected -
private继承:基类所有非private成员在派生类中都变成private
常见错误现象:error: 'xxx' is inaccessible within this context,十有八九是继承方式和访问权限不匹配。别急着改基类,先看你是怎么写的继承声明。
public 继承下子类对象能直接调用父类 public 函数吗?
能,但前提是该函数没被子类同名函数隐藏(注意:不是重写)。C++ 默认不会自动重写,必须显式加 virtual 和 override 才构成多态行为。
- 如果子类定义了和父类同名、同参的函数,且父类没声明
virtual,那父类函数会被完全隐藏,哪怕参数类型略有不同 - 想保留父类接口又扩展逻辑,要么用
using Base::func;在子类中引入,要么老老实实加virtual - 不加
virtual的public继承,只是“接口复用”,不是“运行时多态”
示例:class Derived : public Base { void func(); }; —— 这样写后,Derived d; d.func(); 调的是子类的,Base& b = d; b.func(); 调的才是父类的(除非 func 是虚函数)。
立即学习“C++免费学习笔记(深入)”;
继承时构造函数不自动调用,怎么确保基类初始化正确?
派生类构造函数必须显式调用基类构造函数,否则编译器会尝试调用基类默认构造函数;如果基类没有默认构造函数,就会报错:no matching function for call to 'Base::Base()'。
- 在派生类构造函数初始化列表里写
Base(args),顺序无关紧要,但必须存在 - 基类构造函数执行早于派生类构造函数体,所以不能在派生类构造函数体内“补救”初始化
- 如果基类构造函数是
explicit的,也不能省略初始化列表,更不能用赋值方式绕过
容易踩的坑:把初始化列表写成 Base(args) {}(正确),误写成 Base(args); 在函数体内(这是非法语句,不是调用)。
派生类对象赋值给基类指针安全吗?
安全,这是 public 继承的核心价值之一,也是多态的前提。但要注意指针类型决定你能调用哪些函数——静态类型是基类指针,就只能看到基类声明过的接口。
- 若基类析构函数不是
virtual,用基类指针delete派生类对象会导致派生部分内存泄漏 - 基类指针转回派生类指针必须用
dynamic_cast(需开启 RTTI),且仅对多态类型有效;static_cast强转不检查,风险自担 - 返回基类指针/引用的函数,如果实际返回派生类对象,调用者仍需依赖虚函数机制才能触发子类逻辑
最关键的细节往往藏在析构函数上:只要可能通过基类指针销毁对象,~Base() 就必须是 virtual。这点一旦漏掉,问题可能延迟到程序退出时才暴露。











