一、概念
继承是类设计层次的复用。在 C++ 中,基类(父类)与派生类(子类)构成了这种层次关系。
语法示例:
class Person { /* ... */ };
class Student : public Person { /* ... */ };
继承关系决定了访问权限的传递方式。基类的私有成员虽然被继承到了派生类对象中,但在派生类内部和外部都无法直接访问。如果希望基类成员在派生类中可访问,但对外不可见,应将其定义为 protected。
访问规则遵循以下逻辑:基类其他成员在子类的访问方式取决于 Min(成员在基类的访问限定符,继承方式),即 public > protected > private。
二、基类和派生类对象赋值转换
不同类型对象赋值需要类型转换。例如 int 转 double 是隐式的,但类之间则不同。
父类对象不能赋值给子类对象,即使强转也不行。因为父类对象缺少子类特有的成员变量,强行赋值会导致数据丢失或随机值。
父类对象可以赋值给子类的指针或引用。这是多态的基础。
子类对象可以赋值给父类的对象、指针、引用。 当子类对象赋值给父类对象时,发生的是'切片'操作(Slicing),只拷贝了父类那部分成员,没有发生真正的类型转换。
三、继承中的作用域
作用域查找发生在编译时。子类和父类拥有独立的类域。如果子类定义了与父类同名的成员,会隐藏父类的同名成员,这被称为重定义。
在子类成员函数中,若需访问被隐藏的父类成员,可以使用作用域解析运算符 :: 显式指定。
注意: 尽量不在继承体系中定义同名成员,以免混淆。如果是成员函数的隐藏,只要函数名相同即构成隐藏,参数列表是否一致不影响隐藏的发生(这与重载不同,重载要求在同一作用域且参数不同)。
class Person {
public:
void fun() { cout << "Person::func()" << endl; }
protected:
string _name = "小李子";
};
class Student : public Person {
public:
// 隐藏了父类的 fun()
void fun(int) { cout << "Student::func(int)" << endl; }
{
cout << _name << endl;
cout << Person::_num << endl;
}
:
_num = ;
};


