
在c++中,继承与多态是面向对象编程的核心特性。通过继承,子类可以复用并扩展父类的功能;而多态则允许同一接口表现出不同的行为,主要依靠虚函数机制实现。
继承的基本结构
继承让一个类(派生类)获取另一个类(基类)的成员变量和成员函数。语法格式如下:
class Base {
public:
void func() { cout << “Base func” << endl; }
virtual void vfunc() { cout << “Base vfunc” << endl; }
};
class Derived : public Base {
public:
void func() { cout << “Derived func” << endl; }
void vfunc() override { cout << “Derived vfunc” << endl; }
};
上述代码中,Derived 继承自 Base,采用公有继承方式。此时,Derived 类会拥有 Base 类的全部公有成员。注意:普通函数 func() 是静态绑定,而 vfunc() 被声明为 virtual,支持动态绑定。
虚函数与动态绑定
多态的关键在于虚函数。当基类中的函数被声明为 virtual,派生类重写该函数后,通过基类指针或引用调用该函数时,会根据实际对象类型决定调用哪个版本。
立即学习“C++免费学习笔记(深入)”;
示例:
Base* ptr = new Derived();
ptr->vfunc(); // 输出: Derived vfunc
这里虽然指针类型是 Base*,但指向的是 Derived 对象,且 vfunc 是虚函数,因此调用的是 Derived 的实现。这种机制依赖于虚函数表(vtable)和虚函数指针(vptr),每个包含虚函数的类都有一个 vtable,记录了虚函数的实际地址。
纯虚函数与抽象类
若希望某个类不能被实例化,并强制派生类实现特定函数,可使用纯虚函数:
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override { cout << “Drawing Circle” << endl; }
};
Shape 是抽象类,无法创建实例。只有实现了 draw() 的派生类(如 Circle)才能被实例化。这是实现接口规范的常用方式。
析构函数应为虚函数
当通过基类指针删除派生类对象时,若基类析构函数不是虚函数,可能导致派生部分未被正确释放。
正确做法:
class Base {
public:
virtual ~Base() { cout << “Base destroyed” << endl; }
};
class Derived : public Base {
public:
~Derived() { cout << “Derived destroyed” << endl; }
};
此时 delete ptr(指向 Derived 的 Base*)会先调用 Derived 的析构函数,再调用 Base 的,确保完整清理资源。
基本上就这些。掌握继承结构和虚函数机制,就能有效设计出灵活、可扩展的C++类体系。关键点是理解静态绑定与动态绑定的区别,以及合理使用 virtual 和 override 关键字。不复杂但容易忽略细节。