在本地作用域C++中初始化时避免对象破坏



我正在进行一个网络项目,需要初始化try-catch块中的一个对象。我希望表示套接字的对象在销毁时关闭套接字,但在使用之前必须避免关闭套接字。套接字用一个整数值这样简单的东西来表示,这就是为什么关闭它很容易,或者很难避免。

本质上,我有以下(简化的(代码:

#include <iostream>
using namespace std;
struct Foo {
int v;
Foo() {
cerr << "Foo default constructor with v = " << v << ".n";
}
Foo(int newV) : v(newV) {
cerr << "Foo constructor with v = " << v << ".n";
}
~Foo() {
cerr << "Foo destructor with v = " << v << ".n";
}
};
int main()
{
Foo foo;
try {
foo = Foo(3);
} catch (...) {
// handle exception
}
}

产生以下输出:

Foo default constructor with v = 0.
Foo constructor with v = 3.
Foo destructor with v = 3.
Foo destructor with v = 3.

这对我来说是个问题,因为Foo已经用值3销毁了两次。一次,在程序结束时,以及在分配操作后退出try块后一次。

我的问题是:我可以通过破坏一个对象的默认值并就地构造它来实例化它吗,而不是构造另一个对象并执行赋值?

当然,也有一些变通方法,比如使用new,但我不想被迫在任何地方取消引用对象,我还想确保它在出现错误时被销毁(当然,为此我可以使用一些指针包装器(。我也不想使用一些单独的C风格初始化方法,因为我认为这很难看。我也有其他成员在我的";Foo";类,所以我需要在作业期间执行某种破坏,这很不方便。理想情况下,我很想看到类似的东西

Foo foo;
try {
Foo foo(3);
} catch (...) {
// handle exception
}

但我不能这样做,因为这会导致重新声明,或者更确切地说是影子声明,除此之外,更局部的Foo对象无论如何都会被销毁。

我刚写完这个问题就想到了。使用移动分配。

采用原始代码,并将以下方法添加到类定义中:

Foo & operator=(Foo && other) {
swap(v, other.v);
return *this;
}

这样,当构造一个对象仅将其分配给其他对象时,将调用此方法,并且它将简单地交换v成员中的值。other对象将立即被销毁;旧的";CCD_ 6的值。

注意在默认情况下为v分配一些无意义的值,可能是-1

现在,程序的输出是

Foo default constructor with v = 0.
Foo constructor with v = 3.
Foo destructor with v = 0.
Foo destructor with v = 3.

这正是我想要的。

最新更新