基类private成员在派生类中不可见,仅因访问权限受限;public继承下基类public/protected成员保持原访问级,protected/private继承会降级;构造需显式初始化列表;多继承二义性用作用域解析或虚继承解决;重写须基类virtual+派生类override。

基类成员在派生类里“看不见”?检查访问控制和继承方式
派生类默认不能访问 private 成员,哪怕是在同一个类定义里写继承也不行。这是最常卡住人的地方——不是语法错,是权限拦住了。
常见错误现象:error: 'xxx' is private within this context,尤其当基类把构造函数或关键字段设为 private 时。
- 基类的
public成员,在public继承下仍是public;在protected或private继承下会降级 - 基类的
protected成员,在public和protected继承下保持protected;在private继承下变成private - 别用
private继承除非真想“隐藏接口”,它会让所有基类成员在派生类中变成私有,外部和子类都不可见
单继承时构造函数怎么调?必须显式转发基类参数
派生类构造函数不会自动调用基类构造函数,C++ 不会帮你猜参数。漏写初始化列表,轻则编译失败,重则调用默认构造(如果存在),导致对象处于未预期状态。
使用场景:基类没有默认构造函数,或者你需要传特定值初始化父部分。
立即学习“C++免费学习笔记(深入)”;
- 必须用初始化列表写法:
Derived(int x) : Base(x) { } - 如果基类构造函数是
explicit的,这里也必须显式调用,不能靠隐式转换 - 多个基类参数要按声明顺序传递,顺序错会导致编译错误或静默行为异常
class Base {
public:
Base(int a, const std::string& s) : val(a), name(s) {}
private:
int val;
std::string name;
};
class Derived : public Base {
public:
Derived(int x, const std::string& n) : Base(x, n) {} // 必须这样
};
多继承出现二义性?用作用域解析或虚继承破局
两个基类都有同名函数或成员,派生类直接调用会报 error: request for member 'xxx' is ambiguous。这不是设计缺陷,是语言强制你明确意图。
性能影响:虚继承会带来额外指针开销和间接寻址,仅在需要共享同一份基类子对象时才用;普通多继承无额外成本。
- 临时解决:用
Base1::func()或Base2::func()显式指定 - 根本解决:如果两个基类本应共享一个基类实例(比如都继承自
Interface),就把继承改成virtual public Interface - 注意:虚继承后,最派生类负责构造虚基类,中间继承者不能调用其构造函数
派生类重写函数不生效?确认是否加了 virtual 和 override
没加 virtual 的基类函数,派生类里同签名函数只是隐藏(hiding),不是重写(overriding)。通过基类指针调用,永远执行基类版本。
容易踩的坑:只在派生类加 override,但基类忘了加 virtual,编译器会直接报错,而不是静默忽略。
- 基类函数必须声明为
virtual,派生类对应函数加上override是强推荐做法 - 参数类型、const 限定、引用/值语义必须完全一致,否则仍是隐藏,不是重写
- 返回类型协变只允许指针/引用类型变为其派生类,基础类型(如
int)不能改
final 关键字对重写的限制,这些点一旦混用就容易出定位困难的问题。实际写的时候,宁可多写一行 Base::func(),也别依赖编译器猜测你的意图。











