解读一段代码

keaiting 2008-08-29 03:37:06
#include <iostream>
using namespace std;
class A
{
public:
~A(){cout<<"~A()";}
};
class B
{
public:
virtual ~B(){cout<<"~B()";}
};
class C:public A,public B
{
public:
~C(){cout<<"~C()";}
};
int main()
{
C *c = new C;
B *b1 = dynamic_cast<B*>(c);
A *a2 = dynamic_cast<A*>(b1);
delete c;
a2 = NULL;
if (b1 == NULL)
{
cout<<"################"<<endl;
return 1;
}
else
{
cout<<"@@@@@@@@@@@@@@"<<endl;
return 0;

}
输出结果是~C()~B()~A(),为什么?
如果中间改成delete a2;则输出~A()后停滞不前,为什么啊?
...全文
51 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2008-08-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ttkk_2007 的回复:]
你delete了,当然先调用自己的析构函数,在调用的父类的

如果中间改成delete a2;则输出~A()后停滞不前,为什么啊?
========================
不为什么,崩了,不是new的就不用delete
[/Quote]

不对,这不是这个意思,lz也不是这个意思,因为如果是a2,那么,a2所指向的,根本不是和c同一个地方!
因为c还要保留一个虚表指针,所以,会出错!
太乙 2008-08-29
  • 打赏
  • 举报
回复
c++ 指出:当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分(也就是 timekeeper 部分)很可能已被销毁,这就导致了一个古怪的“部分析构”对象。这是一个泄漏资源,破坏数据结构以及消耗大量调试时间的绝妙方法。 排除这个问题非常简单:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象,包括全部的派生类部分。
e_sharp 2008-08-29
  • 打赏
  • 举报
回复
class A
{
public:
virtual ~A(){cout < <"~A()";} //基类的析构函数是virtual
};
coverallwangp 2008-08-29
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;
class A
{
public:
~A(){cout <<"~A()";}
};
class B
{
public:
virtual ~B(){cout <<"~B()";}
};
class C:public A,public B
{
public:
~C(){cout <<"~C()";}
};
int main()
{
C *c = new C;
B *b1 = dynamic_cast <B*>(c);
A *a2 = dynamic_cast <A*>(c);//这个地方你的好像不对
delete c;
a2 = NULL;
if (b1 == NULL)
{
cout <<"################" <<endl;
return 1;
}
else
{
cout <<"@@@@@@@@@@@@@@" <<endl;
return 0;

}
}


析构函数的调用顺序是先自己,后父类的。

如果中间改成delete a2;则输出~A()后停滞不前,为什么啊?
========================
不是new的指针是不能delete的
veloting 2008-08-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ttkk_2007 的回复:]
你delete了,当然先调用自己的析构函数,在调用的父类的

如果中间改成delete a2;则输出~A()后停滞不前,为什么啊?
========================
不为什么,崩了,不是new的就不用delete
[/Quote]
up
ttkk_2007 2008-08-29
  • 打赏
  • 举报
回复
你delete了,当然先调用自己的析构函数,在调用的父类的

如果中间改成delete a2;则输出~A()后停滞不前,为什么啊?
========================
不为什么,崩了,不是new的就不用delete
太乙 2008-08-29
  • 打赏
  • 举报
回复


#include <iostream>
using namespace std;
class A
{
public:
~A(){cout <<"~A()";}
};
class B
{
public:
virtual ~B(){cout <<"~B()";}
};
class C:public A,public B
{
public:
~C(){cout <<"~C()";}
};
int main()
{
C *c = new C;
B *b1 = dynamic_cast <B*>(c);
A *a2 = dynamic_cast <A*>(c);
delete c;
a2 = NULL;
if (b1 == NULL)
{
cout <<"################" <<endl;
return 1;
}
else
{
cout <<"@@@@@@@@@@@@@@" <<endl;
return 0;

}
}

veloting 2008-08-29
  • 打赏
  • 举报
回复
你把dynamic_cast去掉就会变成~C()~C()~C()了,而你进行了动态的类型转换,他们的类型都变掉了,因为析构函数是virtual的,他们会调用自己那个类型的析构函数
后面的问题就不太清楚了

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧