虚与实:C++中的虚函数,纯虚,实例
创始人
2025-06-01 01:02:47
0

虚函数

基类希望派生类定义适合自己的版本,就把这些函数声明成虚函数

虚函数的工作原理:

虚函数表(vtable):每个包含虚函数的类都有一个与之关联的虚函数表。虚函数表是一个包含指向类的虚函数实现的指针的数组。当派生类覆盖基类的虚函数时,派生类的虚函数表将包含指向派生类的实现的指针,而基类的虚函数表将包含指向基类实现的指针。

每个包含虚函数的类的对象都有一个指向与其关联的虚函数表的指针。这个指针通常存储在对象内存布局的开始处,以便快速访问。这意味着每个对象都有一个指向它所属类的虚函数表的指针。

当通过基类指针调用虚函数时,编译器生成的代码会首先使用this指针找到对象的虚函数表指针,然后在虚函数表中查找相应的函数指针,最后调用该函数。这个过程在运行时发生,因此允许多态行为。

虚函数的调用在程序运行时(runtime)进行解析。这也被称为动态绑定或运行时多态性。在编译时,编译器不知道应该调用哪个类的虚函数实现,因为具体的实现取决于程序运行时指向的对象类型。

由于虚函数的工作原理,导致下面两个现象

构造函数不能是虚函数,而析构函数应是虚函数

构造函数不能是虚函数:

  • 虚函数的主要目的是实现多态性,允许派生类覆盖基类的实现。然而,在构造对象时,必须明确调用哪个类的构造函数。构造函数是用来初始化对象状态的,包括基类和派生类的成员变量。如果构造函数是虚函数,那么在构造派生类对象时,将不清楚应该调用哪个构造函数来初始化基类部分。这将导致对象状态未定义。

  • 在构造函数执行期间,虚函数表(vtable)尚未完全建立。虚函数表是C++用来实现动态多态性的机制,它存储了指向虚函数实现的指针。在构造函数中,虚函数表会根据当前正在构造的类来设置。因此,在构造基类时,虚函数表将指向基类的实现,而在构造派生类时,虚函数表将更新为指向派生类的实现。如果构造函数是虚函数,将无法保证正确的虚函数表设置,从而导致未定义行为。

析构函数可以(且通常应该)是虚函数,以确保在通过基类指针删除派生类对象时正确调用派生类的析构函数。这样可以确保正确清理派生类对象占用的资源。

inline,static,constructor三种函数不能带virtual

由于inline函数在编译时就会被嵌入,它们不能是虚函数,因为虚函数的调用是在运行时解析的

static成员函数没有this指针,它们不能是虚函数,因为虚函数依赖于this指针来访问虚函数表

constructor构造函数是用于初始化对象的状态的,它们不能是虚函数。虚函数是用于实现多态性的,而在构造对象时,需要明确调用哪个类的构造函数来初始化对象

纯虚函数

是一种在C++中表示抽象类的方法。抽象类是一种不能实例化的类,它主要用于作为其他类的基类。纯虚函数是一个在基类中声明的虚函数,它没有定义具体的实现,而是强制派生类提供实现。换句话说,包含纯虚函数的类无法创建实例,必须通过其派生类创建实例。

class Animal {
public:virtual void makeSound() const = 0; // 纯虚函数
};class Dog : public Animal {
public:void makeSound() const override {std::cout << "Woof!" << std::endl;}
};class Cat : public Animal {
public:void makeSound() const override {std::cout << "Meow!" << std::endl;}
};int main() {// Animal animal; // 错误:不能创建抽象类的实例Dog dog;Cat cat;dog.makeSound(); // 输出:Woof!cat.makeSound(); // 输出:Meow!return 0;
}

虚拟继承

菱形继承(也称钻石继承)会导致派生类具有多个顶级基类的成员变量和成员函数实例,导致编译错误

为了解决菱形继承问题,C++引入了虚拟继承(virtual inheritance)。虚拟继承确保顶级基类在派生类中只有一个实例。要使用虚拟继承,只需在基类前加上virtual关键字

相关内容

热门资讯

研究了10000名消费者,我们... 对如今的年轻人(Z世代)来说,买东西早就不是简单的“需要”,而是一种表达“我是谁”、寻找“我们是谁”...
商界优选×伯位数智合作发布会暨... 1月9日下午,“数智赋能・商赢未来——商界优选×伯位数智战略合作发布会暨企业数字化转型赋能论坛”在维...
百工传艺谢晓飞:传统手工艺与A... 文:深蓝从《中华手工》副主编到文创产业平台创始人,她试图用AI为传统工艺打造一座“数字诺亚方舟”。在...
黄金站上4600美元再创新高,... 1月12日亚洲早盘,COMEX黄金期货价格直线拉升,站上每盎司4600美元,时隔两周再度刷新历史新高...
AI宠物玩具狂潮来了 作者 | 黄昱编辑 | 周智宇在最近的国际消费电子展CES 2026上,一只有呼吸、能回应、有个性的...
2025中国数字经济学自主知识... 2026年1月10日,由中央财经大学国家财经战略研究院、中央财经大学中国互联网经济研究院联合中国移动...
沪深两市成交额超2万亿元,超3... 1月12日早盘,A股继续放量上涨。截至发稿时,沪深两市成交额连续第10个交易日突破2万亿,较上一日此...
奶粉召回风波中的嘉必优收到监管... 卷入雀巢全球预防性召回婴幼儿奶粉事件的ARA供应商——嘉必优生物技术(武汉)股份有限公司(下称“嘉必...
华特气体:股东拟合计减持不超2... 新京报贝壳财经讯 1月11日,华特气体发布公告称,股东厦门华弘多福投资合伙企业(有限合伙)、厦门华和...
延江股份:筹划购买资产,股票继... 新京报贝壳财经讯 1月11日,延江股份发布公告称,公司正计划通过发行股份等方式收购资产,并拟同步募集...