为什么把c++类的析构函数声明为虚函数?
来源:互联网 发布:金属探测器软件 编辑:程序博客网 时间:2024/06/01 21:25
如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥?
class BaseCls{public: BaseCls() { printf("BaseCls()\n"); } ~BaseCls() { printf("~BaseCls()\n"); } void test_func() { printf("Base::test_func()\n"); }};class SubCls : public BaseCls{public: SubCls() { printf("SubCls()\n"); } ~SubCls() { printf("~SubCls()\n"); } void test_func() { printf("SubCls::test_func()\n"); }};int main(void){ BaseCls *base = new SubCls;; base->test_func(); delete base; return 0;}
编译运行:
在main()函数中,定义了BaseCls类型指针,根据赋值兼容性原则,该指针可以指向动态生成子类SubCls对象的地址,此时动态生成的SubCls对象已经被充当基类使用,因为BaseCls中的test_func()函数是普通函数(并非虚函数)不能发生多态,所以打印的是基类的”Base::test_func()\n”。
”delete base;”代码我们希望用来释放SubCls的空间,即调用SubCls的析构函数,释放完毕后BaseCls的析构函数。然而编译器只是根据指针类型是BaseCls而只是调用BaseCls的析构函数,SubCls的析构函数得不到调用,若在SubCls构造函数中动态分配的空间,在析构函数释放空间,那么这样就造成内存泄漏了。
如何改进?让基类BaseCls的析构函数声明为虚函数,使其在delete base时发生多态即可:
class BaseCls{public: //... virtual ~BaseCls() { printf("~BaseCls()\n"); } //...};
编译运行:
将构造函数中声明为virtual后,编译器就不会简单的只根据base指针的类型而决定调用对象的构造函数,而是依据指针base所指向的实际对象而调用其构造函数,这不就是多态吗?
最后,再补充两个问题?
(1) 析构函数可以被声明为虚函数,那构造函数可以声明为虚函数吗?
答案是不可以。因为虚函数的调用依靠于虚函数表。然而在构造函数执行完毕后,虚函数表指针才被正确初始化。
(2) 构造函数可以被声明为虚函数,那么构造函数的实现体中,可以实现多态吗?
答案还是不可以。因为析构函数一旦别调用,稀虚函数表指针就会销毁了。那么同理,在构造函数中实现体中也不可能发生多态行为,因为在构造函数执行时,虚函数表指针还没被正确初始化。
- 为什么把c++类的析构函数声明为虚函数?
- 为什么要将基类的析构函数声明为虚函数
- c++(重载、覆盖、隐藏)&&什么情况下,类的析构函数应该声明为虚函数?为什么?
- 为什么把成员函数声明为虚函数
- 为什么不能把构造函数声明为虚函数
- 为什么要把父类的虚构函数声明为虚的
- 为什么构造函数不能声明为虚函数,析构函数可以声明为虚函数
- 为什么基类的析构函数声明为虚函数?
- 为什么析构函数常声明为虚函数
- 为什么析构函数常声明为虚函数
- 为什么析构函数常常声明为虚函数
- 为什么析构函数常声明为虚函数
- 为什么析构函数常声明为虚函数?
- c++ 为什么析构函数必须声明为虚函数
- C ++为什么经常将析构函数声明为虚函数?
- C++里父类的析构函数为什么声明为virtual
- 为什么构造函数不可以声明为虚函数,而析构函数最好声明为虚函数
- 为什么构造函数不可以被声明为虚函数而析构函数有时候必须声明为虚函数
- TypeError: Value passed to parameter 'targets' has DataType float32 not in list of allowed values: i
- css的边界和补白
- Android_非UI:SpannableString
- ShaderLab: Blending
- window下的常见命令
- 为什么把c++类的析构函数声明为虚函数?
- css之边框
- vue2.0之Vuex使用实例
- 最大子序列和
- html之div和span
- JavaScript DOM扩展
- imageview和imagebutton
- HDU 6144 Arithmetic of Bomb(字符串+大数取余模板)
- 元标签