-2

ScreenShot #1: Sample(Sample&) {...) // No Error without using "const" enter image description here ScreenShot #2: Destructor is called twice, when copy-constructor is not included. enter image description here

When I run this code in VC++2010, I found results surprizing, please have a look:

#include <iostream>
using namespace std;

class Sample {
public:
   Sample() { cout<<"Sample().\n"; }
   // Sample (Sample&) { cout<<"Sample(Sample&).\n"; }
   ~Sample() { cout<<"~Sample().\n"; }
};

void fx() {
   throw Sample();
}

int _tmain(int argc, _TCHAR* argv[])
{
   try { fx(); }
   catch (Sample&) { cout<<"Caught Sample.\n"; }
   return 0;
}

Please tell why without including copy-constructor in example, destructor is being called twice. And having so causes Abort() if we're freeing heap in destructor for example.

Also I know that a copy of object is created of the throwing object, but why it is not calling copy-constructor for that.

Please see the attached screen shot for code and output.

4

1 回答 1

2

这似乎是 VC++ 编译器中的一个错误(功能?:)),它已经存在了一段时间(但是我没有任何链接可以直接支持这个声明,我没有时间继续搜索。我想我不过,我自己也遇到过一两次。)这仍然发生在 VC++ 2012 中。

始终定义一个复制 ctor 是一种很好的编码习惯,即使您不使用它也是如此。这是三法则的一部分。不过有一些警告。

  1. VC++ 在抛出时尝试执行复制 ctor 时将使用对象的上下文而不是调用者。因此,即使标记为私有,它仍然可以访问。这可能是一个遗留问题,尽管我找不到任何特定于该事实的东西。

  2. VC++ 将允许在抛出时使用具有非常量参数的复制 ctor。这也是允许在移动范式实施之前转移资源的遗留问题。我只发现了一些模糊不清的事情。不,VC++ 似乎没有使用移动范例来抛出对象,所以如果您尝试实现移动构造函数,仍然会发生这种情况。

有关移动构造函数的更多信息,您可以在此处查看

请注意,微软似乎会根据它是否会破坏太多东西来挑选它将实施的 C++ 标准的哪一部分。出于这个原因,我认为我不想加入 M$ 的编译器开发团队。:/

于 2013-03-11T17:13:40.680 回答