社区
C++ 语言
帖子详情
[讨论]如何处理构造函数中资源分配失败?
shadowstar
2003-12-25 03:18:32
C++太灵活了。。。
...全文
330
28
打赏
收藏
[讨论]如何处理构造函数中资源分配失败?
C++太灵活了。。。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
28 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
hchinside
2003-12-30
打赏
举报
回复
class A
{
public:
A()
try : initialize list
{
.....
}
catch (...)
{}
}
这样可以处理初始化列表中的异常
sharkhuang
2003-12-29
打赏
举报
回复
你可以看看 more effcet c++
详细介绍
aaassd
2003-12-29
打赏
举报
回复
还有谁说,大师们都哪里去了?
shadowstar
2003-12-29
打赏
举报
回复
还有很多方法的,没人说,明天结贴吧。。。
jeckyz
2003-12-28
打赏
举报
回复
构造函数抛出异常本来就不是好方法(大师门通常是避而不谈,或者只是说不要这么干),但也确实没有很好的方法,我的看法是:干脆就 delete this 算了,可以抛出异常,但绝对不要在构造函数里处理它,因为这样很容易死循环的,在外部 catch 它,输出个错误信息。具体怎么处理,我想还是实际问题实际分析吧,因为构造错误肯定是个严重问题,很难有一个定则,或许把别的错误解决了,这个问题也就迎韧而解了。
shadowstar
2003-12-28
打赏
举报
回复
处理构造函数失败难道不包括异常处理的方式么?
[quote Jinhao(辣子鸡丁)]
我上面的代码没有用异常而直接进行delete this;导致a=new A;进行了赋值,我是故意这样做的,原因是构造函数未完成,对象就不会构造成功,delete this;就毫无意义,如果有了delete this;会带来极其隐蔽的BUG。
[/quote]
首先你不应该故意这么做! 即使有异常发生构造还是完成了。
这个版好象很多人的嘛,看来大家对这个不感兴趣。
唉,没意思。。。
Jinhao
2003-12-28
打赏
举报
回复
楼主的问题已经从[如何处理构造函数中资源分配失败]讨论到[是否在构造函数的异常处理中需要delete this;]
我上面的代码没有用异常而直接进行delete this;导致a=new A;进行了赋值,我是故意这样做的,原因是构造函数未完成,对象就不会构造成功,delete this;就毫无意义,如果有了delete this;会带来极其隐蔽的BUG。
当然用了异常更好,他会阻止后面的动态分配
shadowstar
2003-12-28
打赏
举报
回复
Jinhao(辣子鸡丁)
这样写当然一点意义都没有了,而且还有个大BUG。
要改成这样的:
A(){
delete this; //有了delete this;
throw(-1);
}
int main(int argc, char* argv[])
{
A* a = NULL; // 初始化指针变量为NULL
B* b = NULL; // 养成好习惯
try {
a = new A();
b = new B();
} catch(...) {
delete a; // 此时 a == NULL,delete也不会出错
delete b; // 正确
}
return 1;
}
Jinhao
2003-12-28
打赏
举报
回复
楼主,你先仔细看完下面的代码
class A
{
public:
A(){
delete this; //有了delete this;
}
~A(){
cout<<"Deleted A"<<endl;
}
};
class B{};
int main()
{
A* a;
B* b;
a=new A;
b=new B;
delete a;
....省掉很多对class B实例对象操作的代码
delete b;
}
这段代码看上去毫无问题,其实有个严重的BUG隐藏在class A的默认构造函数中。你会发现程序会在...处和delete b;处出错
那是因为A的默认构造函数中的delete this;导致B的实例对象分配在A的this指针所指的内存上,当你delete a;就破坏了B实例对象的堆内存
shadowstar
2003-12-28
打赏
举报
回复
delete this;
会调用析构函数,所以不需要在构造函数中delete[] pA;
transformers
2003-12-27
打赏
举报
回复
初学者问:
“但是如果遇到pA=new A[10];这样分配的话,你用delete this;就破坏了堆,当你delete []pA;就有问题了”
破坏了堆 是什么意思? 能否给小弟解释一下! 谢了!
Jinhao
2003-12-27
打赏
举报
回复
绝对不用担心char* str[10];占用的内存
首先class A的构造函数并没有完成,这说明对象构造失败,这时抛出异常后,这个class A的实例对象占用的内存就被归还系统了。
我提供的这段代码中,可以用delete this;
但是如果遇到pA=new A[10];这样分配的话,你用delete this;就破坏了堆,当你delete []pA;就有问题了
shadowstar
2003-12-27
打赏
举报
回复
to Jinhao(辣子鸡丁)
在构造过程中,char* str[10];所占的内存是被分配了的,如果不用 delete this; 的话还是有一定浪费。
shadowstar
2003-12-27
打赏
举报
回复
请问delete []str[i]前面的“[]”是什么意思?
对应的 str[i]=new char[1024*1024*1024]; //要来就来狠的
表示删除数组。
Zaster
2003-12-27
打赏
举报
回复
请问delete []str[i]前面的“[]”是什么意思?
初学ing,请各位大侠不要吝啬啊,感激不尽。
Jinhao
2003-12-27
打赏
举报
回复
一个实例对象的构造
第一步,分配足够的内存,如果失败就是栈溢出或抛出std::bad_alloc的异常,所以在这步你不用担心内存泄露,而且这一步你是不能插手的,如果这步成功,就进入第二步
第二步,调用构造函数,在通常情况下,如果构造函数为空或没有进行动态内存分配,你就不用关心内存泄露了
你需要关心的是构造函数中有动态内存分配
class A
{
char* str[10];
public:
A(){
for(int i=0;i<10;i++)
str[i]=NULL; //对str[]初始化,这是必须的,不然再后面delete就会出现问题
try{
for(int i=0;i<10;i++)
str[i]=new char[1024*1024*1024]; //要来就来狠的
}
catch(bad_alloc){
for(int i=0;i<10;i++)
delete []str[i]; //放心,即使delete NULL是不会出问题的
//delete this;
throw; //就抛出这个bad_alloc
}
}
~A()
{
for(int i=0;i<10;i++)
delete []str[i];
}
};
int main()
{
A *pA=NULL;
try{
pA=new A;
}
catch(bad_alloc){
cout<<"Out of memory"<<endl;
}
delete pA;
return 0;
}
pA是用NULL初始化的,即使在给A分配内存时(第一步)失败,这样就不会导致后面的delete pA出错。
在class A 的构造函数中的异常处理中没有提供delete this;提供了就完了
shadowstar
2003-12-27
打赏
举报
回复
up
shadowstar
2003-12-26
打赏
举报
回复
too ALL
如何处理构造函数中资源分配失败?
肯定不只有异常一种方法,而且异常也不一定在任何情况下都是最好的方法。
以前的贴子我都翻过了,基本都说得是异常,没有一个全面的。提出这个问题只是希望抛砖引玉,和大家讨论一下各种方法所适用的环境。
象我上面的代码,抛出的异常,但实际上CFoo已经被构造了。有一个方法是在构造函数中删除自己,这样即没有给调用者返回指针,又不会造成资源泄漏。因为是独创,没见有人用过,所以想讨论一下。
CFoo() {
cout << "construct CFoo." << endl;
// an error occurred
delete this;
throw -1;
}
还有其它的方法,我不想一个人在这儿干吼,烦请各位高手出招。
transformers
2003-12-26
打赏
举报
回复
还有就是你用考虑吗?用异常不是很好吗!
transformers
2003-12-26
打赏
举报
回复
分配失败,Foo仍然是NULL吧?!
那还用什么delete?
加载更多回复(8)
面向对象和
构造函数
JavaSE就是一种标准版,是Java
中
的基础部分,Java各种框架和产品都是基于JavaSE,也就是JavaSE是Java向上发展的基础,它允许开发和部署在桌面、服务器、嵌入式环境和实时环境
中
使用的Java应用程序。JavaSE 包含了...
C++
构造函数
中
抛出的异常
1、标准C++
中
定义
构造函数
是一个对象构建自己,分配所需资源的地 方,一旦
构造函数
执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证...
c++
构造函数
抛出异常
1、标准C++
中
定义
构造函数
是一个对象构建自己,分配所需资源的地方,一旦
构造函数
执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证对象的...
关于
构造函数
抛出异常的
讨论
C++
构造函数
抛异常问题
构造函数
中
抛出的异常
1、标准C++
中
定义
构造函数
是一个对象构建自己,分配所需资源的地方,一旦
构造函数
执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证对象...
C++ 语言
64,637
社区成员
250,559
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章