为什么C++不能有虚构造函数,却可以有虚析构函数
来源:互联网 发布:细说php第四版 编辑:程序博客网 时间:2024/05/16 23:47
class B{ public : virtualvoid m1(); virtualvoid m2(); }; class D : public B{ virtualvoid m1(); }
一、C++的动态绑定使用vtable(虚成员函数表)来实现。vtable支持运行时查询,使系统可以将某一函数名绑定到vtable的特定入口地址。
例如上段代码的虚函数表为:
虚成员函数 入口地址 虚成员函数 入口地址B::m1 0x7723 D::m1 0x99a7 //重定义的B::m2 0x23b4 D::m2 0x23b4 //完全继承
由于系统执行虚函数时,要从对象的vtable找到函数入口地址,而且vtable是存储于对象的内存空间中。假如对象没有实例化,就找不到vtable。因此,构造函数不能是vittual。
但是,析构函数一般都需要加上virtual,假如定义Base *b = new Deriver; Deriver是Base的子类,并且~Base()不为virtual。那么当对象被注销时,系统只会调用~Base(),而不会调用~Deriver(),因为b是Base类型,已被静态绑定析构函数。如果基类或子类用new创建了内存空间,就必须通过析构函数销毁。因此必须使用vitual析构函数,实现动态绑定。
另外:从另一个角度也可以看出构造函数不能为虚函数,1,虚函数的作用在于通过父类的指针或者引用调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建对象时自动调用的,不可能通过父类或者引用去调用,因此就规定构造函数不能是虚函数。
二、构造函数不需要是虚函数,也不允许是虚函数,因为创建一个对象时我们总是要明确指定对象的类型,尽管我们可能通过实验室的基类的指针或引用去访问它
但析构却不一定,我们往往通过基类的指针来销毁对象。这时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。
#include <iostream>using namespace std;class A{public: A() { cout << "A" << endl; } ~A() { cout << "~A" << endl; }};class B:public A{public: B() { cout << "B" << endl; } ~B() { cout << "~B" << endl; }};class C:public B{public: C() { cout << "C" << endl; } ~C() { cout << "~C" << endl; }};int main(){ A *b = new B; cout << endl; A *c = new C; cout << endl; delete b; cout << endl; delete c; return 0;}
析构函数加上 virtual 后:
0 0
- 为什么C++不能有虚构造函数,却可以有虚析构函数
- 为什么C++不能有虚构造函数,却可以有虚析构函数
- 为什么C++不能有虚构造函数,却可以有虚析构函数
- 构造函数为什么不能是虚构造函数
- 为什么有虚析构函数,没有虚构造函数啊
- c++中为什么不允许虚构造函数?
- 有虚析构函数,没有虚构造函数
- 为什么不能把构造函数设为虚函数,却可以把析构函数设为虚函数
- C++虚构造函数
- 虚构造函数
- 所谓虚构造函数
- 为什么虚构函数不允许抛出异常
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚析构函数、纯虚析构函数、虚构造函数
- C++中的虚构造函数
- 为什么线程函数不能有返回值
- 析构函数为什么不能有参数???
- 内联元素的padding,margin,border等不起作用的原因
- HDU 5915 (二分 主席树)
- 本地git仓库提交远程失败的解决办法
- 【c++】单链表
- web常用标签
- 为什么C++不能有虚构造函数,却可以有虚析构函数
- Android完美满足你所有的拍照或从相册中选取照片
- Hdu1323 Perfection Time
- openstack中的rpc通信
- Mysql性能优化(1) 从新建一个表开始
- 笔试算法学习--买票找零问题(卡特兰数)
- 三十岁那年,我的梦想是年薪十万
- Ubuntu下,搭建java环境
- 八大排序--希尔排序