虚析构函数
来源:互联网 发布:字幕自动生成软件 编辑:程序博客网 时间:2024/06/05 00:37
虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象。
例子#include<iostream>
using namespace std;
class b
{
public:
b(){cout<<"base constructor"<<endl;}
~b(){cout<<"base destoyer"<<endl;}
virtual void dosth(){cout<<"base do some things"<<endl;}
};
class c:public b
{
public:
c(){cout<<"son constructor"<<endl;
ptr = new char[256];
*ptr = 'c';
}
~c(){cout<<"son destroyer"<<endl;
delete ptr;
}
void dosth(){cout<<"son do something"<<endl;
cout<<*ptr<<endl;
}
private:
char *ptr;
};
int f()
{
//c c_t;
//c_t.dosth();
b *b_e = new c();
b_e->dosth();
delete b_e;
}
int main()
{
f();
system("pause");
}
可以看到,delete父类指针时不会调用之类的析构函数。如果将父类的析构函数声明为virtual,则会调用之类的析构函数。
using namespace std;
class b
{
public:
b(){cout<<"base constructor"<<endl;}
~b(){cout<<"base destoyer"<<endl;}
virtual void dosth(){cout<<"base do some things"<<endl;}
};
class c:public b
{
public:
c(){cout<<"son constructor"<<endl;
ptr = new char[256];
*ptr = 'c';
}
~c(){cout<<"son destroyer"<<endl;
delete ptr;
}
void dosth(){cout<<"son do something"<<endl;
cout<<*ptr<<endl;
}
private:
char *ptr;
};
int f()
{
//c c_t;
//c_t.dosth();
b *b_e = new c();
b_e->dosth();
delete b_e;
}
int main()
{
f();
system("pause");
}
如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。
所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。
如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。
所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
虚析构函数举例
这里是一个例子:
class awov { // awov = "abstract w/o
// virtuals"
public:
virtual ~awov() = 0; // 声明一个纯虚析构函数
};
这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:
awov::~awov() {} // 纯虚析构函数的定义
这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这就是说,即使是抽象类,编译器也要产生对~awov的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,最后还是得回去把它添上。
注意:如果声明虚析构函数为inline,将会避免调用它们时产生的开销,但编译器还是必然会在什么地方产生一个此函数的拷贝。
0 0
- 虚析构函数、纯虚析构函数
- 虚析构函数,纯虚析构函数~~~
- 构造函数 虚函数 虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 纯虚函数、虚函数、虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚函数,虚析构函数,虚函数表
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 全表扫描出现db file sequential read
- myeclipse设置字体快捷方式
- 铁道部新客票系统的设计(一)
- Java JNI学习(二)
- hdu 3436 Queue-jumpers(Splay)
- 虚析构函数
- C++服务器与android客户端通信程序————C++服务器程序
- oracle多表关联update语句
- 铁道部新客票系统的设计(二)
- openstack维护过程中遇到的问题
- 做技术需要有专研的精神
- 铁道部新客票系统的设计(三)
- svn使用别名 映射ip,出差时候就方便多了
- ZOJ 1005 Jugs(模拟 special judge,也可以BFS)