careercup-C和C++ 13.6
13.6 基类的析构函数为何要声明为virtual?
解答:
用对象指针来调用一个函数,有以下两种情况:
- 如果是虚函数,会调用派生类中的版本。
- 如果是非虚函数,会调用指针所指类型的实现版本。
析构函数也会遵循以上两种情况,因为析构函数也是函数嘛,不要把它看得太特殊。 当对象出了作用域或是我们删除对象指针,析构函数就会被调用。
当派生类对象出了作用域,派生类的析构函数会先调用,然后再调用它父类的析构函数, 这样能保证分配给对象的内存得到正确释放。
但是,如果我们删除一个指向派生类对象的基类指针,而基类析构函数又是非虚的话, 那么就会先调用基类的析构函数(上面第2种情况),派生类的析构函数得不到调用。
例如:
class Foo
{
public:
void f();
}; class Bar: public Foo
{
public:
void f();
} Foo *p=new Bar();
p->f();
调用p->f()最后将会调用Foo::f(),这是因为p是指向Foo的指针,而f()不是虚函数。
为确保p->f()会调用继承关系最末端的子类的f()实现,我们需要将f()声明为虚函数。
现在,回到前面的析构函数。析构函数用于释放内存和资源。Foo的析构函数若不是虚拟的,那么,即使p实际上是Bar类型的,还是会调用Foo的析构函数。
这就是为何要将析构函数声明为虚拟的原因——确保正确调用继承关系最末端的子类的析构函数。
例如:
class Base{
public:
Base() { cout<<"Base Constructor"<<endl; }
~Base() { cout<<"Base Destructor"<<endl; }
};
class Derived: public Base{
public:
Derived() { cout<<"Derived Constructor"<<endl; }
~Derived() { cout<<"Derived Destructor"<<endl; }
};
int main(){
Base *p = new Derived();
delete p;
return ;
}
输出为:
Base Constructor
Derived Constructor
Base Destructor
上面结果表明,虽然基类指向的是派生类,但是调用析构函数释放p时,仍然只调用了基类的析构函数。
如果我们把基类的析构函数声明为虚析构函数,这会使得所有派生类的析构函数也为虚。 从而使析构函数得到正确调用。
将基类的析构函数声明为虚的之后,得到的输出是:
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor
因此,如果我们可能会删除一个指向派生类的基类指针时,应该把析构函数声明为虚函数。 事实上,《Effective C++》中的观点是,只要一个类有可能会被其它类所继承, 就应该声明虚析构函数。
careercup-C和C++ 13.6的更多相关文章
- [CareerCup] 17.13 BiNode 双向节点
17.13 Consider a simple node-like data structure called BiNode, which has pointers to two other node ...
- [CareerCup] 18.13 Largest Rectangle of Letters
18.13 Given a list of millions of words, design an algorithm to create the largest possible rectangl ...
- [CareerCup] 13.1 Print Last K Lines 打印最后K行
13.1 Write a method to print the last K lines of an input file using C++. 这道题让我们用C++来打印一个输入文本的最后K行,最 ...
- [CareerCup] 13.2 Compare Hash Table and STL Map 比较哈希表和Map
13.2 Compare and contrast a hash table and an STL map. How is a hash table implemented? If the numbe ...
- [CareerCup] 13.3 Virtual Functions 虚函数
13.3 How do virtual functions work in C++? 这道题问我们虚函数在C++中的工作原理.虚函数的工作机制主要依赖于虚表格vtable,即Virtual Table ...
- [CareerCup] 13.4 Depp Copy and Shallow Copy 深拷贝和浅拷贝
13.4 What is the difference between deep copy and shallow copy? Explain how you would use each. 这道题问 ...
- [CareerCup] 13.5 Volatile Keyword 关键字volatile
13.5 What is the significance of the keyword "volatile" in C 这道题考察我们对于关键字volatile的理解,顾名思义, ...
- [CareerCup] 13.6 Virtual Destructor 虚析构函数
13.6 Why does a destructor in base class need to be declared virtual? 这道题问我们为啥基类中的析构函数要定义为虚函数.首先来看下面 ...
- [CareerCup] 13.7 Node Pointer 节点指针
13.7 Write a method that takes a pointer to a Node structure as a parameter and returns a complete c ...
- [CareerCup] 13.8 Smart Pointer 智能指针
13.8 Write a smart pointer class. A smart pointer is a data type, usually implemented with templates ...
随机推荐
- windows ping RPi 2B
/************************************************************************* * windows ping RPi 2B * 声 ...
- (十三)学习CSS之两个class连一起隔空格和逗号
1.时常见到css的这两种种写法: a.两个class隔空格连一起: .class1 .class2{......} b.两个class隔逗号连一起: .class1,.class2{......} ...
- span文字在左背景图片在右
<html><head><meta http-equiv="Content-Type" content="text/html; charse ...
- SharePoint 2010 master page 控件介绍(3) :页面主体内容
转:http://blog.csdn.net/lgm97/article/details/6409217 <!-- ===== 页面滚动区域开始 ====================== ...
- 5、四大组件之一-Activity与Intent
一.Activity的定义及作用 1)官方定义:Activity是Android应用程序提供交互界面的一个重要组件 . 也是Android最重要的组件之一 2)Activity是业务类 , 是承载应用 ...
- FFmpeg 2.0编译配置
./configure --enable-shared --enable-doc --enable-ffmpeg --enable-ffplay --enable-ffprobe --enable- ...
- HDU 5699 货物运输 二分判定
转自:http://blog.csdn.net/jtjy568805874/article/details/51480479 #include <cstdio> #include < ...
- HDU 1078 FatMouse and Cheese 记忆化搜索DP
直接爆搜肯定超时,除非你加了某种凡人不能想出来的剪枝...555 因为老鼠的路径上的点满足是递增的,所以满足一定的拓补关系,可以利用动态规划求解 但是复杂的拓补关系无法简单的用循环实现,所以直接采取记 ...
- 用Python操作Excel2007 及以上的版本读写,来自官方的Demo
大牛请略过,新手可以参考,具体见下面的代码注释, 另外一个问题,想学习这个语言,最好还是英语牛一些,可以去官网多看看有用的类库,汉语的资料不是很全 #运行环境 3.4,下面这个操作Excel的包是针对 ...
- android NDK 实用学习(一)-获取java端类及其类变量
近期为android 端项目包装一些c++代码,故学习ndk相关知识,现总结如下: 1,java与c++类型参照图: 2,此测试中使用的java类: package com.dasea.test.co ...