调用构造函数重新初始化对象

是否有可能使用它的构造函数重新初始化一个类的对象?

有点。 给定一个A类:

A a; ... a = A(); 

最后的声明不是初始化,而是赋值,但它可能做你想要的。

从字面上看? 是的,通过使用新的位置。 但首先你必须破坏以前构build的对象。

 SomeClass object(1, 2, 3); ... object.~SomeClass(); // destruct new(&object) SomeClass(4, 5, 6); // reconstruct ... // Final destruction will be done implicitly 

这个价值并不超越纯粹的理论。 不要在实践中这样做。 整个事情是难以描述的。

这是可能的,虽然这是一个非常糟糕的主意。 之所以这样,是因为如果不调用现有对象上的析构函数,就会泄漏资源。

有了这个重大的警告,如果你坚持这样做,你可以使用新的安置。

 // Construct the class CLASS cl(args); // And reconstruct it... new (&cl) CLASS(args); 

不,构造函数只在对象第一次创build时被调用。 写一个新的方法来代替它。

编辑

我不会承认安置新的,因为我不想得到一个宠物猛禽的工作。

看到这个漫画 ,但想想现在的话题…

简短的回答:

不。如果部分对象的预期行为要被初始化多次,那么实现这一目的的最好方法是通过可访问的初始化方法。 你的类的构造函数可以简单地遵循这个方法。

 class C1 { public: C1(int p1, int p2) { Init(p1,p2); } void Init(int p1, int p2) { ... } }; 

Nitpickerangular落:

在创build对象之后,有没有一些令人难以置信的邪恶的方法来在C ++中调用构造函数? 几乎可以肯定,这毕竟是C ++。 但是从根本上来说这是邪恶的,它的行为几乎肯定不是标准所定义的,应该避免。

在C ++ 11中,你可以这样做:

 #include <type_traits> template <class T, typename... Args> void Reconstruct(T& x, Args&&... args) { static_assert(!std::has_virtual_destructor<T>::value, "Unsafe"); x.~T(); new (&x) T(std::forward<Args>(args)...); } 

这允许您使用Reconstruct将任意构造函数parameter passing给任何对象。 这样可以避免必须维护一堆Clear方法,以及在对象发生变化的情况下很容易被忽略的错误,并且Clear方法不再与构造函数匹配。

上述方法在大多数情况下都能正常工作,但如果引用是在具有虚拟析构函数的派生对象中的基础,则会失败。 由于这个原因,上面的实现可以防止使用具有虚拟析构函数的对象。

是的,你可以作弊,并使用新的安置。
注意:我不build议这样做:

 #include <new> reInitAnA(A& value) { value.~A(); // destroy the old one first. new (&value) A(); // Call the constructor // uses placement new to construct the new object // in the old values location. } 

我通常在现代C ++中编写以下代码:

 SomeClass a; ... a = decltype(a)(); 

这可能不是最有效的方法,因为它有效地构造了同一types的另一个对象并将其赋值给a ,但是在大多数情况下它可以工作,您不必记住a的types,types改变。

可能不是你想到的,但是因为你没有提到它是什么,我想一个答案就是你可以通过控制范围和程序stream程来做到这一点。

例如,你不会写这样的游戏:

 initialize player code for level 1 ... reinitialize player code for level 2 ... etc 

相反,你会努力:

 void play_level(level_number, level_data) { Player player; //gets "re-initialized" at the beginning of each level using constructor //code for level } void game() { level_number = 1; while (some_condition) { play_level(level_number, level_data); ++level_number; } } 

(非常粗略的传达想法,不意味着可以远程编译。)

正如上面的一些答案所build议的那样,而不是像以下那样进行破坏和重新初始化,最好做一个如下的任务。 下面的代码是exception安全的。

  T& reinitialize(int x, int y) { T other(x, y); Swap(other); // this can't throw. return *this; }