继承与派生基础概念
继承允许从已有类(基类/父类)创建新类(派生类/子类),实现代码复用和层次化设计。子类自动获得基类成员(除构造函数、析构函数、赋值运算符重载和友元外),并可扩展新成员。
语法示例:
cpp
class Derived : public Base {
// 新增成员
};
继承方式与权限控制
继承方式决定基类成员在子类中的访问权限:
- 公有继承(public):基类public→子类public;基类protected→子类protected;基类private→不可访问
- 保护继承(protected):基类public/protected→子类protected;基类private→不可访问
- 私有继承(private):基类public/protected→子类private;基类private→不可访问
关键点:
基类private成员始终不可直接访问,但会被继承(占用内存)。公有继承最常用,保持基类权限结构不变。
内存布局
子类对象内存包含基类部分和新增成员:
cpp
class Base { int a; };
class Derived : public Base { int b; };
// sizeof(Derived) = sizeof(Base) + sizeof(b)
构造与析构顺序
构造顺序:
- 虚基类(按声明顺序)
- 非虚基类(按继承声明顺序)
- 对象成员(按类内声明顺序)
- 子类自身构造
析构顺序:
与构造完全相反。
示例:
cpp
class A { /*...*/ };
class B { /*...*/ };
class C : public A, public B { /*...*/ };
C c; // 输出:A构造 B构造 C构造 ~C ~B ~A
初始化列表规则
必须显式调用基类构造的情况:
基类无默认构造函数时,需在子类初始化列表中手动调用:
cpp
class Base {
public:
Base(int x) { /*...*/ }
};
class Derived : public Base {
public:
Derived(int x, int y) : Base(x), b(y) {}
private:
int b;
};
赋值兼容规则
公有继承下,子类对象可向上转换:
- 子类对象赋值给基类对象(发生切片,仅复制基类部分)
- 子类对象初始化基类引用(无拷贝,安全)
- 子类指针赋值给基类指针(存储子类首地址)
禁止反向操作:
基类对象不能自动转为子类(可能导致越界)。
代码示例:
cpp
Base* ptr = new Derived(); // 允许
// Derived* d = new Base(); // 错误