继承
1. 什么是继承
概念:继承是面向对象编程中的一个核心概念,允许一个类(派生类或子类)继承另一个类(基类或父类)的属性和方法。
原理:继承提供了代码复用机制,派生类可以扩展或修改基类的行为。
用法:使用class Derived : public Base
声明派生类继承基类。
案例代码:
class Base {
public:
void show() {
cout << "Base class show()" << endl;
}
};
class Derived : public Base {
public:
void show() {
cout << "Derived class show()" << endl;
}
};
int main() {
Derived d;
d.show(); // 输出 Derived class show()
return 0;
}
2. 继承的特性
传递性:如果类B继承自类A,类C继承自类B,则类C间接继承自类A。
不对称性:继承关系不是双向的,即派生类可以访问基类的公有成员,但基类不能访问派生类的成员。
3. 继承的分类
单继承:一个类只继承一个基类。
多继承:一个类继承多个基类。
4. 基类成员调用的函数的二义性问题
概念:当派生类与基类有同名函数时,会产生调用哪个函数的二义性问题。
用法:通过使用作用域解析运算符::
或在派生类中重写基类函数来解决。
5. 菱形继承
概念:当两个基类继承自同一个基类,而派生类又继承这两个基类时,会产生菱形继承问题。
问题:可能导致基类部分被实例化多次,造成资源浪费。
6. 解决菱形继承
虚继承:使用虚继承可以确保基类只被实例化一次。
案例代码:
class Base {};
class Left : virtual public Base {};
class Right : virtual public Base {};
class Derived : public Left, public Right {};
int main() {
Derived d;
return 0;
}
7. 不可被继承
概念:构造函数、拷贝构造函数、析构函数、友元和静态成员不能被继承。
原理:这些成员与类的具体实现细节相关,不适合被继承。
8. 继承方式
public:基类的公有成员和保护成员在派生类中保持原有的访问权限。
private:基类的公有成员和保护成员在派生类中变为私有成员。
protected:基类的公有成员和保护成员在派生类中变为受保护成员。
9. 继承后的访问权限
概念:继承不会改变基类成员的访问权限。
原理:派生类可以访问基类的公有成员和保护成员,但不能访问基类的私有成员。
10. 继承的构造、析构顺序
构造顺序:基类的构造函数先于派生类的构造函数执行。
析构顺序:派生类的析构函数先于基类的析构函数执行。
11. 继承与组合类
概念:在派生类中,基类对象作为成员变量被包含。
构造顺序:成员对象的构造函数在派生类构造函数中先执行。
12. 模板的继承
概念:模板类可以被继承。
用法:派生类需要指定模板参数以匹配基类。
13. 基类的静态成员被继承的特性
概念:静态成员不属于类的任何对象,因此不能被继承。
原理:派生类可以访问基类的静态成员,但它们不属于派生类。
14. 类型兼容性原则
概念:派生类对象可以被当作基类对象使用。
原理:基类指针可以指向派生类对象,这是多态的基础。
15. 隐藏与重定义
隐藏:派生类中与基类同名的函数会隐藏基类中的同名函数。
重定义:派生类可以重写基类的虚函数,以提供特定的实现。
案例代码:
class Base {
public:
virtual void func() {
cout << "Base::func()" << endl;
}
};
class Derived : public Base {
public:
void func() {
cout << "Derived::func()" << endl;
}
};
int main() {
Base* b = new Derived();
b->func(); // 输出 Derived::func()
delete b;
return 0;
}
继承是面向对象编程中实现代码复用和扩展功能的重要机制。正确使用继承可以提高代码的可维护性和可扩展性。