基类的析构函数 纯虚函数为什么要是虚函数

【求教】C++中父类析构函数是虚函数,及多态性,求解惑,谢谢了_c++吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:268,051贴子:
【求教】C++中父类析构函数是虚函数,及多态性,求解惑,谢谢了收藏
(1)Mammal为父类,有析构函数~Mammal() {cout&&&~Mammal()&&&}Dog为子类,public继承,有析构函数~Dog() {cout&&&~Dog()...&&&}Mammal *p=new Dog(); p=0;运行结果是:~Mammal()(2)、如果将Mammal的析构函数改为虚函数,即virtual ~Mammal() {cout&&&~Mammal()&&&}则运行结果为:~Dog()...
~Mammal()问题:在(2)情况下,是不是子类、父类对象所占的堆空间都被释放??就像Dog *pdog=new Dog();delete pdog()时的析构原理一样,先释放子类、再释放父类对象的堆空间???在(1)情况下,仍然是子类、父类对象所占的堆空间都被释放了吗??如果是这样的话,为什么没调用子类析构函数??
[SALOON索龙]服装整烫及配套设备的一次革命!!!
作业么……
非虚函数调用时编译时决定调用哪个函数。
这算是答案吗,百度到的:(1)基类的析构函数不是虚函数,在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:只是释放了基类的资源,而没有调用继承类的析构函数。一般情况下,这样的删除只能够删除基类对象,而不能删除子类对象,形成了删除一半现象,造成内存泄漏。(2)基类的析构函数被定义为虚函数,在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:先释放了继承类的资源,再调用基类的析构函数。
如果不是虚函数,这么写代码估计没有为子类分配内存空间,因而也就无所谓释放问题。可以自己写个代码测试下。Mammal *p=new Dog(); cout&&sizeof(*p)&&cout&&sizeof(Dog)&&cout&&sizeof(Mammal)&&//比较一下三者的大小
已有人解答 来晚了
第一种是子类对象可以被当作基类对象来处理
#include&iostream&using std::using std::class Mammal{public: Mammal(int x){a=x;} ~Mammal() {cout&&&~Mammal()&&&}};class Dog:public Mammal{public: Dog(int x,int y):Mammal(x){b=y,c=y;} ~Dog() {cout&&&~Dog()&&&}};void main(){ Dog&dog=*(new Dog(1,2)); Mammal*p=& cout&&p-&a&&' '&&dog.a&&' '&&dog.b&&' '&&dog.c&& cout&&p-&a&&' '&&dog.a&&' '&&dog.b&&' '&&dog.c&&}
天气预报广告,北京中视万方全面代理,每晚19:31黄金时间播出;收视率高,!
#include&iostream&using std::using std::class Mammal{public: Mammal(int x){a=x;} ~Mammal() {cout&&&~Mammal()&&&}};class Dog:public Mammal{public: Dog(int x,int y):Mammal(x){b=y,c=y;} ~Dog() {cout&&&~Dog()&&&}};void main(){ Dog&dog=*(new Dog(1,2)); Mammal*p=& cout&&p-&a&&' '&&dog.a&&' '&&dog.b&&' '&&dog.c&& cout&&p-&a&&' '&&dog.a&&' '&&dog.b&&' '&&dog.c&& delete &}这个程序会产生问题
“我只想知道,第一种情况下,new Dog()出来的所有堆空间(new Dog()出的空间包括父类对象和子类对象部分)都被释放了吗”我虽解决不了你的问题,但算是尽力了。要完全解惑,可能要用到别的工具。
————————————有谁知道虚表吗?————————————————#include&iostream&using std::using std::class Mammal{public: Mammal(int x){a=x;} ~Mammal() {cout&&&~Mammal()&&&}};class Dog:public Mammal{public: Dog(int x,int y):Mammal(x){b=y,c=y;} ~Dog() {cout&&&~Dog()&&&}};void main(){ Mammal *p=new Dog(1,2);
cout&&sizeof(*p)&&' '&&sizeof(Dog)&&' '&&sizeof(Mammal)&&}//输出结果:4
#include&iostream&using std::using std::class Mammal{public: Mammal(int x){a=x;} virtual ~Mammal() {cout&&&~Mammal()&&&}};class Dog:public Mammal{public: Dog(int x,int y):Mammal(x){b=y,c=y;} ~Dog() {cout&&&~Dog()&&&}};void main(){ Mammal *p=new Dog(1,2);
cout&&sizeof(*p)&&' '&&sizeof(Dog)&&' '&&sizeof(Mammal)&&}//输出结果:8
ISO/IEC C++ 1z (WG21 N4567)5.3.5 Delete [expr.delete]3 In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.delete 基类指针还没有虚析构直接 UB 了就别瞎掰了。
试图以实现解释语义和/或行为的,按误导论处,警告一次。连带上个月前科,如不能停止误导,将作封禁处理。
第一种是子类对象可以被当作基类对象来处理
第一种是静态连编,编译时决定对象,第二是动态连编,运行时决定对象。这样说能懂不
为了研究多态的实现机制,我必须研究反汇编了,就是不知道要花多少时间。
情况1 貌似书上说是未定义行为
首先,父类对象是可以存储子类对象的,但是只保留了其中继承自父类的,因为父类对象无法完全存储子类对象(一般情况下,子类对象所占的内存大于等于父类对象所占的内存)而其子类所独有的那一部分数据被编译器截断了(为了便于理解可以参考double截断为float)所以当函数不是虚函数时,看似是存储了子类对象,实际调用了父类的函数(因为实际上只保留了继承自父类的那一部分数据);但是当父类有虚函数时,编译器会生成一份虚函数表,编译器无权截断虚函数表,而且又是使用对象指针来访问,所以访问的函数就是变量中实际存储的对象的函数,当然,前提是父类的虚函数在子类中重新覆盖,
看来关于虚函数表的事,争得不可开交,我来说一下,认为对的赞一下,认为错的说出你的理由:当一个类中存在虚函数时,编译器会自动生成虚函数表,这个表是由编译器生成和管理的,你不用关心这张表究竟在哪里。当你用这个类定义对象的时候,这个对象会隐含的生成一个VPTR指针;但发生多态时,是具体的对象vptr指向自已的虚函数表,查找相应的函数;(父子都有虚函数表)
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或C++中为什么基类析构函数一般要声明为虚函数-学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
> 信息中心 >
C++中为什么基类析构函数一般要声明为虚函数
来源:互联网 发表时间: 9:54:58 责任编辑:鲁晓倩字体:
为了帮助网友解决“C++中为什么基类析构函数一般要声明为虚函数”相关的问题,学网通过互联网对“C++中为什么基类析构函数一般要声明为虚函数”相关的解决方案进行了整理,用户详细问题包括:RT,我想知道:C++中为什么基类析构函数一般要声明为虚函数,具体解决方案如下:解决方案1:
类析构函数要声明为虚函数这样派生类调用缉光蝗叱豪癸通含坤析构函数才能层层回调,释放资源。这也是虚函数的作用--提供回调的指针。
解决方案2:
作用于派生类的回调
解决方案3:
xiaoxiaoxia666 正解
解决方案4:
因为他不是真正的函数
1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答
相关文章:
<a href="/cse/search?q=<inputclass="s-btn"type="submit"text="<inputclass="s-btn"type="submit"text="<buttonhidefocusclass="s-btnjs-ask-btn"text="我要提问
<a href="/cse/search?q=2012年5月 专题开发/技术/项目大版内专家分月排行榜第二2010年3月 C/C++大版内专家分月排行榜第二
2012年4月 Linux/Unix社区大版内专家分月排行榜第三2011年7月 Linux/Unix社区大版内专家分月排行榜第三2010年2月 C/C++大版内专家分月排行榜第三
2012年 总版技术专家分年内排行榜第一
2013年 总版技术专家分年内排行榜第七2011年 总版技术专家分年内排行榜第五2009年 总版技术专家分年内排行榜第九
2012年8月 C/C++大版内专家分月排行榜第三2012年7月 C/C++大版内专家分月排行榜第三
2003年9月 C/C++大版内专家分月排行榜第二2002年6月 C/C++大版内专家分月排行榜第二2002年4月 C/C++大版内专家分月排行榜第二
2007年3月 C/C++大版内专家分月排行榜第三2007年2月 C/C++大版内专家分月排行榜第三2007年1月 C/C++大版内专家分月排行榜第三2003年7月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。为什么C++基类析构函数写成虚函数
为什么C++基类析构函数写成虚函数
下面的代码举例:
// virtual.cpp : 定义控制台应用程序的入口点。
#include &stdafx.h&
#include &string.h&
#define MAXLEN 128
class CEmployee{
char m_Name[MAXLEN];
char m_Depart[MAXLEN];
CEmployee(){
printf(&CEmployee 类构造函数被调用了/n&);
~CEmployee(){
printf(&CEmployee 类析构函数被调用了/n&);
getchar();
protected:
class COperator:public CEmployee{
char m_Password[MAXLEN];
COperator(){
strcpy(m_Name,&MR&);
printf(&COperator 子类的构造函数被调用了/n&);
getchar();
~COperator(){
printf(&COperator 子类析构函数被调用/n&);
getchar();
int _tmain(int argc, _TCHAR* argv[])
CEmployee *oper = new COperator() ;
函数的返回结果是:
可以看到&#20540;调用了父类的析构函数,而子类的析构函数没有被调用,那么可想而知,如果在子类的构造函数中对某个成员函数在堆空间中分配了空间,而之类没有被调用,是不是会造成内存泄漏呢?答案是肯定的,那有什么办法可以解决这种情况下出现的内存泄漏呢?那就是把父类的析构函数写为虚函数,看下面的代码:
// virtual.cpp : 定义控制台应用程序的入口点。
#include &stdafx.h&
#include &string.h&
#define MAXLEN 128
class CEmployee{
char m_Name[MAXLEN];
char m_Depart[MAXLEN];
CEmployee(){
printf(&CEmployee 类构造函数被调用了/n&);
virtual ~CEmployee(){
printf(&CEmployee 类析构函数被调用了/n&);
getchar();
protected:
class COperator:public CEmployee{
char m_Password[MAXLEN];
COperator(){
strcpy(m_Name,&MR&);
printf(&COperator 子类的构造函数被调用了/n&);
getchar();
~COperator(){
printf(&COperator 子类析构函数被调用/n&);
getchar();
int _tmain(int argc, _TCHAR* argv[])
CEmployee *oper = new COperator() ;
运行结果:
因此,在写父类的时候,最好将其析构函数写为虚函数。这样可以防止比较瘾避的内存泄漏。
我的热门文章
即使是一小步也想与你分享2013年12月 C/C++大版内专家分月排行榜第二2013年12月 Linux/Unix社区大版内专家分月排行榜第二2013年11月 C/C++大版内专家分月排行榜第二2013年10月 C/C++大版内专家分月排行榜第二
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
2013年6月 Linux/Unix社区大版内专家分月排行榜第二2013年5月 Linux/Unix社区大版内专家分月排行榜第二2013年3月 Linux/Unix社区大版内专家分月排行榜第二2013年1月 Linux/Unix社区大版内专家分月排行榜第二2012年12月 Linux/Unix社区大版内专家分月排行榜第二2012年8月 Linux/Unix社区大版内专家分月排行榜第二2011年12月 Linux/Unix社区大版内专家分月排行榜第二2011年10月 C/C++大版内专家分月排行榜第二2011年10月 Linux/Unix社区大版内专家分月排行榜第二
2012年6月 C/C++大版内专家分月排行榜第三2012年6月 PHP大版内专家分月排行榜第三2012年5月 C/C++大版内专家分月排行榜第三2012年3月 Linux/Unix社区大版内专家分月排行榜第三2012年2月 Linux/Unix社区大版内专家分月排行榜第三2011年11月 C/C++大版内专家分月排行榜第三
2014年10月 C/C++大版内专家分月排行榜第三2014年4月 C/C++大版内专家分月排行榜第三
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 c 析构函数 虚函数 的文章

 

随机推荐