c++ - 在对象的析构函数被调用后使用对象

标签 c++ exception destructor

<分区>

Possible Duplicate:
Can a local variable’s memory be accessed outside its scope?

代码:

#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

我的问题是如何访问其析构函数调用已完成的对象 ob 的成员变量 b

最佳答案

使用被破坏的对象是未定义的行为。这意味着您现在可能会出现这种行为,但无法保证您会在其他时间出现这种情况。未定义的行为比常规错误更危险,因为它更难检测,如本例所示。

更新:在一些评论之后,我将解释为什么 OP 的代码会产生该输出。

try 功能 block 在 C++ 中是一个有点晦涩的功能。您可以将函数的整个主体包围在 try block 中,并使用相应的 catch。这是,而不是:

void foo()
{
  try
  {
    //...
  }
  catch (/*whatever*/)
  {
    //...
  }
}

你可以这样写:

void foo()
try
{
    //...
}
catch (/*whatever*/)
{
  //...
}

这实际上不是很有用,但对于构​​造函数可能有点用处,因为这是将初始化列表包含在 try block 中的唯一方法。因此,OP 的 A 构造函数代码等同于:

A()
try
: b()
{
  throw 4;
}
catch(...)
{
  cout << "Catched in A() handler : ob.b= " << ob.b<<endl;
}

我说过这只是有点用处,因为您不能使用您在 catch block 中构建的对象;如果你在 try block 中抛出异常,异常将离开构造函数主体,因此该对象将永远不会被构造,并且任何构造的数据成员将在进入 catch 之前立即被销毁> 阻止。但它可能对日志记录有一定的用处。

现在,众所周知,构造函数(假设我们没有使用 nothrow 版本)只能做两件事:

  1. 返回一个构造好的对象
  2. 抛出异常

在这个构造函数中我们抛出异常,但是异常在 catch block 中被捕获。那么现在发生了什么?调用构造函数的代码将返回什么?我们不能返回构造对象,因为我们没有,所以只有一个选择:catch block 必须抛出。在这种情况下,这实际上是标准要求的。如果我们没有显式抛出,编译器会在 catch block 的末尾默默地添加一条 throw; 指令。因此,详细说明一下,构造函数等同于以下内容:

A()
try
: b()
{
  throw 4;
}
catch(...)
{
  cout << "Catched in A() handler : ob.b= " << ob.b<<endl;
  throw;
}

这就是异常被捕获两次的原因:一次在 A 构造函数中,一次在 main() 中。

关于c++ - 在对象的析构函数被调用后使用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13067765/

相关文章:

c++ - Windows 7下编译Qt3D

c++ - 成员变量的通用声明

objective-c - 在数据库类iPhone中使用异常

c# - 为什么接口(interface)不能有构造函数和析构函数?

c++ - 手动调用析构函数总是糟糕设计的标志吗?

c++ - 将对象成员数组与字符串进行比较

c++ - 在 C++ 中使用带参数的 Fortran90 子例程

exception - Vaadin 7 获取屏幕宽度

java - 当路径名正确时,为什么它会给我一个 FileNotFoundException 异常?

c++ - 何时调用 C++ 析构函数?