虚函数相关讨论
2017-08-30 09:43
204 查看
下列关于虚函数相关说法正确的有? |
(2) 构造函数可以声明为虚函数 (x)
(3) 析构函数不可以声明为虚函数 (x)
(4) 抽象类中至少包含一个纯虚函数 (√)
C++中 的虚函数的作用主要是实现了多态的机制。而虚函数是通过虚函数表(V-Table)实现的。
构造函数为什么不能声明为虚函数?
1 构造一个对象的时候,必须知道对象的实际类型。如果构造函数是虚函数,虚函数行为在运行期间才能确定实际类型。对象还未构造成功,编译器无法知道对象的实际类型,所以构造函数不可以为虚函数。
2 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表还没有被初始化,将无法进行。
析构函数为什么声明为虚函数?
如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。
顺序:
构造函数执行时先调用基类的构造函数,其次才调用派生类的构造函数。
析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。
包含至少一个纯虚函数的类视为抽象类
虚函数之于析构函数的讨论 |
#include<stdio.h> class A { public: A(){ printf("A");} ~A(){ printf("~A");} }; class B: public A { public: B(){ printf("B");} ~B(){ printf("~B");} }; int main() { A* c = new B[2]; delete[] c; return 0; }
结果:ABAB~A~A
1 声明的是基类的指针,基类的析构函数不是虚函数,不会调用派生类的析构方法。
2
#include<stdio.h> class A { public: A(){ printf("A");} virtual ~A(){ printf("~A");} }; class B: public A { public: B(){ printf("B");} ~B(){ printf("~B");} }; int main() { A* c = new B[2]; delete[] c; return 0; }
结果:ABAB~B~A~B~A
2 当基类的析构函数是虚函数时,基类指针指向派生类对象的空间被释放时会自动调用派生类的析构函数。
3
#include<stdio.h> class A { public: A(){ printf("A");} ~A(){ printf("~A");} }; class B: public A { public: B(){ printf("B");} ~B(){ printf("~B");} }; int main() { B* c = new B[2]; delete[] c; return 0; }
结果:ABAB~B~A~B~A
4
#include<stdio.h> class A { public: A(){ printf("A");} virtual ~A(){ printf("~A");} }; class B: public A { public: B(){ printf("B");} ~B(){ printf("~B");} }; int main() { B* c = new B[2]; delete[] c; return 0; }
结果:ABAB~B~A~B~A
由程序3、4可知,不管基类析构函数加不加virtual,只要是声明的是派生类的指针,并且实际指向的实例是派生类的,会先调用派生类的析构方法,然后级联调用父类的析构方法。
1 vs 2小结
在C++中,析构函数的作用是:当一个对象被销毁时,调用析构函数对类对象和对象成员进行释放内存资源。
当我们定义一个指向派生类类型对象指针时,构造函数按照从基类到派生类的顺序被调用,但是当删除指向派生类的基类指针时,派生类的析构函数没有被调用,只是调用了基类的析构函数,此时派生类将会导致内存泄漏
我们需要将基类的析构函数声明为虚函数,此时在调用析构函数的时候是根据ptr指向的具体类型来调用析构函数,此时会调用派生类的析构函数。
相关文章推荐
- main 函数参数中 argc/argv的相关讨论和使用
- Linux C——网络通信的相关函数
- Perl函数:字符串相关函数
- 摄像机模型与标定(二):opencv2相关函数介绍
- send函数特点及相关问题
- WebForms和MVC这2个模型都很棒,由相关讨论想到的
- Socket一些函数相关的返回值
- c语言字符相关函数
- PHP中对已打开文件资源进行操作的相关函数
- linux 时间相关函数的用法
- 和字符串CString类相关的一些常用的函数
- container_of和list_for_each_entry 及其相关函数的分析
- 非相关话题讨论:关于大峡!
- SD--模拟创建订单(相关的函数列表的介绍系列篇(4))
- Libevent源码分析-----与event相关的一些函数和操作
- redis rdb流程和相关函数逻辑
- Openssl中大数以及RSA相关函数介绍
- js中几个正则表达式相关函数使用时g标志的作用
- Day14.成员函数和全局函数//链表货物类//友元函数//操作符重载相关
- 对JavaScript的eval()中使用函数的进一步讨论