c++ 虚函数小结

简介: c++ 虚函数小结

       主要是Effective C++ 中设计到virtual用法的小结。这本书中涉及virtual的条款并不多,主要包括条款07,条款09,条款34,条款35和条款36。先列出这几个条款的标题。

       07 为多态基类声明virtual析构函数

       09 绝不在构造和析构函数中调用virtual函数

       34 区分接口继承和实现继承

       35 考虑virtual函数以外的其他选择

       36 绝对不重新定义继承而来的non-virtual函数

       这里面有几个可以直接在后面加个问号,换成面试题。比如07和09,为什么要为多态基类声明虚析构?为什么不能在构造函数中调用虚函数?答案就是书中比较严谨的叙述,包括例子。但是如何用自己的话语体系来理解?跟着笔者的思路来捋一捋。

       虚函数到底是用来做什么的?笼统的说,是为了实现运行期多态。但这种回答好像比较流于表面,并未触及灵魂。其实虚函数本质上是一种不确定,这种不确定可以延迟到运行期,根据基类指针指向的对象来确定调用的归属。所以虚函数主要用于多态基类及其继承体系。如果场景中确定不会出现继承机制,那就不要使用virtual函数(废话,但是),一旦有继承场景,务必将基类的析构函数声明为virtual。唯有如此,new出来的派生类对象才能正常释放。那有没有必要将析构函数声明为纯虚函数?取决于你是否将基类对象设计为虚基类。如果你不打算让一个基类拥有实例,那就可以将它的析构函数设置为纯虚函数。不过这时,这个纯析构函数必须有一份实现,否则在派生类析构之后,基类析构找不到定义会出错。

       其次厘清在继承机制中,pure virtual,impure-virtual以及non-virtual设计的本来用意,这其实是条款34的主要内容。在基类中声明的这三种函数都是为了让基类和派生类拥有统一的接口。但是这三种对派生类的实现有不同的要求。

       基类中的纯虚函数,基类中可以自己提供一份定义,也可以不提供,让派生类自己实现。总结起来是都可以,但目的是为了让派生类自己实现。书中给了一个例子,就是基类提供一份定义,让派生类来调用基类的实现。从代码的简洁度和安全设计考虑,都是很好的思路。

       基类中的虚函数,基类中必须提供自己的定义,派生类选择继承或者重写(override)。如果是复写,那就是有多态的条件了。其实主要目的是为了复写,如果所有的派生类都不打算复写这个函数,那应该去掉virtual,把它变为一个non-virtual函数。

       基类中的non-virtual函数,即普通的成员函数。如上所述,必须是基类和其所有派生类拥有相同的性质,这些性质就放在non-virtual函数中,这样基类写一份实现就好了,不要去复写它。这也是条款36的主要内容。

       条款35的关注点似乎与其他条款关注点不同。它本质上在描述virtual函数的不足,因为基类和派生类型性质的不同,虽然可以借助虚函数来实现。但是一旦构造它们就性质就确定了,以后没办法改变!有没有办法在构造的时候通过不同的参数,构造不同性质的对象,或者中途改变它们的性质?有的。这就是策略模式。然后介绍了一些策略模式具体的实现方法,可以用函数指针,可以用更抽象的tr1::function,将函数指针,可调用对象等封装起来,使用不同形式的策略模式来解决以上问题。

       虚函数是在c++面向对象机制中非常重要的技术。是很多设计模式的基础,若能随心所欲,如臻化境,那实践中便可起到四两拨千斤的效果。

相关文章
|
C++
C++一分钟之-虚函数与抽象类
【6月更文挑战第21天】在C++中,虚函数与抽象类是多态的基础,增进类间耦合与灵活性。虚函数实现动态绑定,抽象类定义不可实例化的接口。关键点包括:记得使用`virtual`,避免滥用虚函数,确保派生类实现纯虚函数。抽象类不能直接实例化,派生类必须实现所有纯虚函数。通过实例代码学习和实践,能更好地掌握这些概念以优化代码设计。
307 2
|
C++
9. C++虚函数与多态
9. C++虚函数与多态
174 0
|
设计模式 编解码 算法
【C/C++ 虚函数以及替代方案】C++ 虚函数的使用开销以及替代方案(三)
【C/C++ 虚函数以及替代方案】C++ 虚函数的使用开销以及替代方案
441 0
|
算法 安全 编译器
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
1516 0
|
算法 Java 编译器
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
474 0
|
存储 编译器 C++
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
375 0
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
384 4
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如<string>、<cstdlib>等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
428 3
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
Serverless C++
C++多态性、虚函数、纯虚函数和抽象类知识网络构造
C++多态性、虚函数、纯虚函数和抽象类知识网络构造