社区
C++ 语言
帖子详情
为什么一个类里可以有几个构造函数而只能有一个析构函数?
writing0
2003-12-29 08:05:33
为什么一个类里可以有几个构造函数而只能有一个析构函数?
...全文
2668
26
打赏
收藏
为什么一个类里可以有几个构造函数而只能有一个析构函数?
为什么一个类里可以有几个构造函数而只能有一个析构函数?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
26 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
hpho
2003-12-31
打赏
举报
回复
为什么要多个析构?
唔~` 我想一个构造对应一个析构.
所以我想仍然有需要多个析构的时候.
事实上多个析构就是继承虚析构.(基类里的是virtual destructor)
所谓多个就是为了有选择性的调用.
所以我认为有这种需求, 但它的表现并不像构造函数那样, 它"多个"表现的方式是继承.
glacierrr
2003-12-31
打赏
举报
回复
好像看候捷先生的书时看到过这个问题的解答,找找看
dongdong715
2003-12-30
打赏
举报
回复
1
呵呵,,有析构函数重栽吗?
abitz
2003-12-30
打赏
举报
回复
1。 flyinger(风往北吹) 的这个程序:
class fly
{
public:
fly(){}
void test() {cout<<"The object exists!";}
~fly(){}
};
int main()
{
fly flyinger;
flyinger.~fly();//那么这个对象时候还存在呢!
flyinger.test();
//如果编译通过的话,运行的结果可以告诉你一点什么东西呢!
}
vs.net2003编译正常通过,结果为:
The object exists!
没看出来flyinger(风往北吹) 想说的是什么意思;这里我只能讲一下自己的看法:
总的看来,这个程序没有编译通不过的理由:dtor只会摧毁对象,不会释放内存。
而flyinger.test();这句会被展开为普通函数调用test(&flyinger)的形式(test非虚),
此时&flyinger会得到合法的地址,因此test(&flyinger)是合法的。这也可以看出,
利用test这种形式是不能判断一个object是否存在的。
2。前面_goolooloo_(_goolooloo_) 说fly的这个dtor什么也不干,是对的,
这符合当前fly的情况。但是,如果fly中有具有non-trivival dtor的data member,
那么这个dtor是会去调用这些data member的dtor的。
关于这点,这里有几个例子:
《1》如果加入一个data member,其具有trivival dtor,那么在析构前后,对object不会
有影响,也就是说,dtor什么也不作。
《2》如果加入一个data member,其具有non-trivival dtor,那么在析构之后,
该data member也会被析构。
《3》如果加入一个virtual function,使object model中含有vptr,那么在析构之后,
该vptr依然有效。个人怀疑是由于可将vptr视为一data member,由于其具有trivival dtor
(vptr为一指针类型),所以fly的dtor不会对它有什么作为。
关于这些,大家可以很容易的写出例子。
3。关于dtor只会摧毁对象,不会释放内存。
前面好像有人认为dtor会释放内存,这是不对的。dtor不会释放内存。
前面这个例子:
int main()
{
fly flyinger;
flyinger.~fly();
flyinger.test();
}
从道理上讲,是不安全的,因为fly的dtor会被调用两次。而对一个object调用两次
dtor,其结果未有定义。(但这里由于fly的dtor其实是trivival的,故无大碍)
因此,我前面写的例子中,是用placement new在object原有的内存上又构造了一个object,来防止对同一个object调用两次dtor的:
void main()
{
aaa b;
b.~aaa(); //这里是有机会写b.~aaa(1, 2);的
new(&b) aaa;
}
尽管这样不是异常安全的(详见exceptional C++),但示意用足已。
总之,关于这个问题,说由于dtor只能被间接由delete或系统调用,因此不能重载,
似乎是说不过去的。个人以为dtor之所以不能被重载,一是由于dtor的工作比较单一,没有
重载的必要,二是由于delete提供了调用dtor的保证,但却没有提供调用不同版本dtor的
语法,导致如果重载dtor,会使调用不明确。其他的原因我暂时还没想到,还望高人指点。
abitz
2003-12-30
打赏
举报
回复
我不明白为什么要显示自己去调用析构函数,一个实体析构两次或多次,有必要吗?
============================================================================
显式调用dtor不是为了将一个实体析构两次或多次,而是就地摧毁对象。
这样可以把对象的摧毁与内存的释放分开,它和把内存的分配与对象的构造
分开是对应的。至于用处,建议您看一下关于对小对象进行内存分配的方面的应用,
比如sgi STL的allocator
cxjddd
2003-12-30
打赏
举报
回复
析构函数应该有足够的信息来完整地释放资源。
而构造函数需要参数来获得足够的信息来生成一个对象。
FredWorks
2003-12-30
打赏
举报
回复
构造函数可以有很多个,
相当于重载一样,
每一个都有自己的特点,
但是只可以选择一个来使用。
析构函数只需要完成是释放,
不想构造函数有很多不同的工作要做,
所以析构函数只有一个。
而且,析构函数只能由系统调用,
而构造函数可以由程序员自己调用。
freelong2003
2003-12-30
打赏
举报
回复
我非常同意ntxs(唉!一个人好难)的看法!!
不同的构造函数可以构造出不同的对象,而析构函数只需要完成相同的功能,就是释放清空。所以根本没有必要有多个析构函数。(这是站在功能的角度上说的)
而站在用户的角度看,我们无需再为对象析构时应该调用哪个析构函数而烦恼了。:)
loveghb
2003-12-30
打赏
举报
回复
大家为什么都想这么复杂
因为构造可以根据参数来,有不同的情况。但是析构一般都一种,所以系统默认就调用拉。
我不明白为什么要显示自己去调用析构函数,一个实体析构两次或多次,有必要吗?
如果你一个对象要分不同的方法析构的话,那你自己写一些函数好了,为什么就一定要用C++规定的析构函数呢?
DELPHI好象就可以有好多析构函数。
我正在学习DELPHI中,好象它的构造和析构都要自己来的。(错了也别怪我!)
baghatur
2003-12-30
打赏
举报
回复
从编译器的角度看,多个构造函数可以通过overload来确认具体调用哪个构造函数。而析构函数呢?析构函数不能有参数,所以你根本无法写出多个析构函数而又能被编译器正确理解。
_goolooloo_
2003-12-30
打赏
举报
回复
在VC的DEBUG模式下,通过查看反汇编代码,可以看到,直接调用析构函数的语句完全没有任何作用.就和没有这一句一模一样.由此看来,析构函数式自动调用的,如果重载了,就会找不出正确的析构函数。
……
14: a->bbb = 345;
0040105B mov ecx,dword ptr [ebp-4]
0040105E mov dword ptr [ecx],159h
15: a->~A();
16: a->fun();
00401064 mov ecx,dword ptr [ebp-4]
00401067 call @ILT+15(A::fun) (00401014)
……
laomai
2003-12-30
打赏
举报
回复
mark
spirix
2003-12-30
打赏
举报
回复
现在给你一块橡皮泥,让你捏成一个人,那么你有多种捏法[多个构造方法],可以捏成欧洲人,亚洲人,白人,黑人,男人,女人...,当你捏好了,让你把你捏好的东西扔掉,你只有一个固定的东西可以扔[一个析构方法],就是你捏好的人!
ipgk
2003-12-30
打赏
举报
回复
析构函数:程序可以直接调用,不能重载。
至于为什么只能有一个,在于它的地位,因为析构函数不作对于外界的接口,所以它不需要参数也没有返回值。
构造函数负责对象的构造,公有函数负责与外界的接口,析构函数负责对象的销毁,对象各个部分都是分工明确的,更有利于对象的使用。
langzi8818
2003-12-29
打赏
举报
回复
不知道。规则可能就是这样的吧,没有那么多为什么
Robin
2003-12-29
打赏
举报
回复
也许编译通不过,因为编译器会自动的添加对象的destructor,会destruct一个已经不存在的对象,就会出错!
Robin
2003-12-29
打赏
举报
回复
就是说我们直接调用了Destructor的结果是什么,对象时候存在呢!
Robin
2003-12-29
打赏
举报
回复
这个问题很好!
不信你这么试:
显式的调用了Destrucor之后会出现什么?
class fly
{
fly();
void test() {cout<<"The object exists!"};
~fly();
}
int main()
{
fly flyinger;
flyinger.~fly();//那么这个对象时候还存在呢!
flyinger.test();
//如果编译通过的话,运行的结果可以告诉你一点什么东西呢!
}
abitz
2003-12-29
打赏
举报
回复
而且你只能通过delete间接调用析构函数,或者用系统调用(在对象生存期结束时),你又怎么为他传递参数呢。
========================================
传递参数是有可能的。
看这个:
struct aaa
{
aaa(){}
~aaa(){cout << "dtor called" << endl;}
};
void main()
{
aaa b;
b.~aaa(); //这里是有机会写b.~aaa(1, 2);的
new(&b) aaa;
}
结果为:
dtor called
dtor called
但是由于delete并不具有跟new等价的语法,使得在delete时无法传递参数,
而delete又肩负调用dtor的责任,则如果存在多个dtor,会使调用不明确。
cai114
2003-12-29
打赏
举报
回复
析构函数一个就够用了
它是用来delete的
我太菜还没想用它来执行别的功能,
加载更多回复(6)
构造函数
、
析构函数
、虚函数
文章目录为什么
构造函数
不能为虚函数?为什么
析构函数
要定义为虚函数?虚函数的工作原理?有关虚函数的
几个
知识点 为什么
构造函数
不能为虚函数? 参考回答: 在类中,
构造函数
用于初始化对象及相关操作。
构造函数
是不能声明为虚函数的,因为虚函数对应
一个
virtual table(虚函数表),这个表的地址是存储在对象的内存空间的。 而在执行
构造函数
前,对象尚未完成创建,内存都没有被分配,所以无法去查询虚函数表...
C++_
构造函数
与
析构函数
构造函数
和
析构函数
都是属于类中的成员函数,在实例化
一个
对象时系统会自动调用该对象的
构造函数
,因此他常用于初始化对象成员变量,
一个
对象在其生命周期中只会调用一次
构造函数
。而
析构函数
与
构造函数
作用”相反“,他是在对象销毁时自动被系统调用的,所以他的任务是清理、释放对象申请的空间资源,
一个
类中
只能
有
一个
析构函数
。
类的6个默认成员函数:
构造函数
、
析构函数
、拷贝
构造函数
、重载运算符、三/五法则
文章目录
构造函数
默认
构造函数
的三种不适用情况第一种第二种第三种 class Date { }; 可以看到,上面那个类没有任何成员,是
一个
空类,但是它真的什么都没有吗? 其实
一个
类在我们不写的情况下,也会生成6个默认的成员函数,分别是:
构造函数
,
析构函数
,拷贝
构造函数
,赋值运算符重载,取地址运算符重载,对const对象取地址运算符的重载
构造函数
构造函数
是特殊的成员函数,它的主要功能就是初始化对象。和我们之前c语言中自己实现的init函数类似。但是有一点不同的是,init是在我们创建完后才自己调用,
深入理解C#
构造函数
与
析构函数
前言:在前面的博文中,我介绍了C#中的
构造函数
,详情戳:C#中的
构造函数
详解,建议收藏!在本博文接下来的部分,我将对
构造函数
、
析构函数
等做一系列的补充,可谓是干货满满!话不多说,开始学习吧! 文章目录一、
构造函数
1、
构造函数
的概念2、
构造函数
的定义3、默认
构造函数
与有参
构造函数
4、静态
构造函数
5、静态
构造函数
和实例
构造函数
的使用二、
析构函数
三、
构造函数
与
析构函数
区别 一、
构造函数
首先,我们要明确C#中
构造函数
是什么,它能做什么,它的特点又是什么?为此,我专门的写了一篇博文介绍C#中的
构造函数
,详情戳:C#
C++ 类
析构函数
C++ 类
析构函数
阅读目录 一、
析构函数
的定义 二、
析构函数
的调用 三、
构造函数
和
析构函数
的调用情况 四、私有
析构函数
回到顶部 一、
析构函数
的定义
析构函数
为成员函数的一种,名字与类名相同,在前面加‘~’没有参数和返回值在C++中“~”是位取反运算符。
一个
类最多
只能
有
一个
析构函数
。
析构函数
不返回任何值,没有函数类型,也没有函数参数,因此它不能被重载。
构造函数
可能...
C++ 语言
65,180
社区成员
250,527
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章