在调用析构函数后使用对象
using an object after it's destructor is called
可能的重复:
可以在其范围之外访问本地变量的内存吗?
代码:
#include <iostream>
using namespace std;
class B{
public:
int b;
B():b(1){}
~B(){cout << "Destructor ~B() " << endl;}
};
class A{
public:
B ob;
A()try{throw 4;}
catch(...){cout << "Catched in A() handler : ob.b= " << ob.b<<endl;}
};
int main()try{
A t;
}
catch(...){cout << "CATCHED in Main" << endl;}
输出:
Destructor ~B()
Catched in A() handler : ob.b= 1
CATCHED in Main
我的问题是如何访问其destructor调用对象b
的成员变量CC_1。
使用破坏的对象是未定义的行为。这意味着您现在可能会得到这种行为,但是没有任何保证您会再获得其他时间。未定义的行为比常规错误更危险,因为它可能很难检测到,如本示例所示。
更新:按照一些评论,我将解释为什么OP的代码会产生该输出。
try
功能块在C 中有些晦涩难懂。您可以围绕try
块内部的函数的整个身体,并带有相应的catch
。这是,而不是:
void foo()
{
try
{
//...
}
catch (/*whatever*/)
{
//...
}
}
您可以写:
void foo()
try
{
//...
}
catch (/*whatever*/)
{
//...
}
这确实不太有用,但是对于构造函数而言可能会略有用,因为这是在try
块中包含初始化列表的唯一方法。因此,A
构造函数的OP代码等效于:
A()
try
: b()
{
throw 4;
}
catch(...)
{
cout << "Catched in A() handler : ob.b= " << ob.b<<endl;
}
我说这只是有用的,因为您无法使用 catch
块内部构造的对象;如果将 try
块内扔进,则例外将离开构造函数,因此该对象将永远不会构造,并且在输入catch
块之前,任何构造的数据成员都会立即破坏。但它可能用于记录目的。
现在,众所周知,构造函数(Asuming我们不使用nothrow
版本)只能做两件事:
- 返回构造的对象
- 投掷例外
在这个构造函数中,我们投掷了,但是例外是在catch
块中捕获的。那么现在会发生什么呢?什么将返回到调用构造函数的代码?我们无法返回构造的对象,因为我们没有,所以只有一个替代方法:catch
块必须投掷。在这种情况下,这实际上是标准要求的。如果我们不明确投掷,则编译器将在catch
块的末端默默添加throw;
指令。因此,详细说明构造函数等同于以下内容:
A()
try
: b()
{
throw 4;
}
catch(...)
{
cout << "Catched in A() handler : ob.b= " << ob.b<<endl;
throw;
}
这就是为什么捕获异常两次的原因:一次在A
构造函数中,一次在main()
中。
,因为当对象被破坏时,其占用的实际记忆仍然存在。但是,它是不确定的行为,并且可能起作用也可能不起作用。
可能是编译器中的错误。
当我运行您的代码时,将按照适当的顺序调用破坏者。输出为:
Catched in A() handler : ob.b= 1
Destructor ~B()
,我无法想象执行catch
中CC_18的任何原因。例外已经在ob
0中捕获。
update
我对编辑感到困惑。最初,是初始化列表尝试/捕获语法,这会有所作为。现在,我可以重现OP的输出,并且确实是UB。我崩溃了。
- 对RValue对象调用的LValue ref限定成员函数
- 检查哪个对象调用了另一个对象的对象方法
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 从 Base 引用对象调用派生类的成员
- 为什么为未删除的对象调用析构函数?
- Qt c++不会为所有对象调用move_slot.为什么?
- 使用在堆栈上创建的对象调用虚拟函数
- 使用基类对象调用Dervied Class函数
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 从类中的对象调用类中的函数的最佳方法
- 派生对象调用的 Base 方法的模板推导
- 如何使用单个对象调用具有相同名称的两个类函数
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 如果类没有任何成员变量,则通过临时对象调用类的成员函数的开销是多少?
- 如何对动态数组中的某些对象调用析构函数
- 如何从列表中存储的对象调用成员函数
- 从线程内的对象调用静态方法
- 从成员对象调用方法
- 当包含它的对象调用其析构函数时,unique_ptr是否未分配
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值