一、初识继承
继承是面向对象编程中实现代码复用的重要手段。它允许我们在保持原有类特性的基础上进行扩展,从而产生新的类,即派生类。这种设计体现了类层次上的复用。
在术语上,原有类被称为基类(Base)、父类或超类;而在其基础上扩展而来的类则称为派生类(Derived)、子类。
语法格式
C++ 中定义继承关系非常简单,只需在类名后加上冒号和继承方式即可:
class Derived : public Base {
// 新增成员
};
这里的 public 表示公有继承,还有 protected 和 private 两种形式。
继承方式与访问权限
继承方式决定了基类成员在派生类中的可见性。
- public 继承:基类的 public 和 protected 成员在派生类中保持原有访问权限。
- protected 继承:基类的 public 和 protected 成员在派生类中变为 protected。
- private 继承:基类的所有成员在派生类中均变为 private。
注意:
- 基类的
private成员无论以何种方式继承,在派生类中都是不可见的。它们虽然被继承到了派生类对象的内存布局中,但语法上限制了访问。 - 如果基类成员不想在类外直接访问,但需要在派生类中使用,应定义为
protected。这是因继承而特有的访问限定符。 - 使用关键字
class时默认继承方式是private,使用struct时默认为public。建议显式写出继承方式以提高可读性。 - 实际开发中通常使用
public继承,很少使用protected或private继承,因为后者会限制成员的可用性,降低扩展维护性。
二、基类和派生类之间的赋值转换
理解对象间的赋值转换对于避免逻辑错误至关重要。
基本特性
- 派生类对象可以赋值给基类的对象、指针或引用。这被称为'对象切片'(Slicing),寓意将派生类中属于父类的部分切下来赋值过去。
- 基类对象不能赋值给派生类对象。
- 基类的指针或引用可以通过强制类型转换赋值给派生类的指针或引用,但这要求基类指针实际指向的是派生类对象,否则不安全。
切片现象演示
子类虽然继承了父类成员,但父类和子类中的同名成员(如 _name, _age)在内存中是独立的。子类包含两部分成员:继承来的父类成员和自身新增的成员。
代码示例:
class Base {
public:
int age;
Base(int a) : age(a) {}
};
class Derived : Base {
:
no;
( a, n) : (a), (n) {}
};
{
;
Base b = d;
Base* pb = &d;
Derived* pd = <Derived*>(pb);
Base* p_obj = ();
Derived* pd2 = <Derived*>(p_obj);
}


