Constructor call to reinitialize an object

Is it possible to reinitialize a class object using its constructor?

+56
c ++ constructor
Jan 29 '10 at 23:53 on
source share
11 answers

Grade. Given class A:

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

the last statement is not an initialization, it is an assignment, but it probably does what you want.

+70
Jan 29
source share

Literally? Yes, using the new placement. But first you must destroy the previously constructed object.

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

The significance of this does not go beyond the purely theoretical. Do not do this in practice. All this is ugly beyond the scope of the description.

+47
Jan 30 '10 at 0:05
source share

Perhaps, although this is a very bad idea. The reason is that without calling destructors on an existing object, you are about to leak resources.

With this basic warning, if you insist on it, you can use the new placement.

 // Construct the class CLASS cl(args); // And reconstruct it... new (&cl) CLASS(args); 
+28
Jan 30 '10 at 0:02
source share

No, constructors are called only when the object is first created. Instead, write a new method.

Edit

I will not recognize the location as new because I do not want to have a predator fan.

Check out this comic , but think about this topic ...

+11
Jan 29 '10 at 23:55
source share

Short answer:

No. If part of your target behavior of an object needs to be initialized several times, then the best way to implement this is with the available initialization method. The constructor of your class may simply defer this method.

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

Nipple angle:

Is there some incredibly evil way to call a constructor in C ++ after creating an object? Almost certainly, this is C ++. But this is fundamentally evil, and this behavior is almost certainly not defined by the standard, and should be avoided.

+10
Jan 29
source share

In C ++ 11, you can do this:

 #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)...); } 

This allows you to use Reconstruct passing arbitrary constructor parameters to any object. This can avoid the need to support a bunch of Clear methods and errors that can easily go unnoticed if the object changes at some point and the Clear method no longer matches the constructor.

The above will work fine in most contexts, but unsuccessfully if the link is linked to a database inside a derived object that has a virtual destructor. For this reason, the implementation described above prevents the use of objects that have a virtual destructor.

+9
May 26 '15 at 13:30
source share

Yes, you can cheat and use a new place. Note: I do not recommend:

 #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. } 
+7
Jan 30 2018-10-10T00:
source share

I usually write the following in modern C ++:

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

This may not be the most efficient way, since it effectively creates another object of the same type a and assigns it a , but it works in most cases, you do not need to remember the type from a , and it adapts if the type changes.

+4
Nov 30 '16 at 16:48
source share

Maybe this is not what you mean, but since you did not indicate why it is important, I believe that one answer will be that you do this by controlling the volume and flow of programs.

For example, you will not write such a game:

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

Instead, you would seek:

 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; } } 

(A very crude scheme to convey an idea, rather than being remotely compiled.)

+2
Jan 30 '10 at 0:25
source share

Instead of destroying and repeating the initialization, as suggested by some of the above answers, it is better to complete the task as shown below. The code below is safe for exceptions.

  T& reinitialize(int x, int y) { T other(x, y); Swap(other); // this can't throw. return *this; } 
+2
Jan 30 '10 at 4:51
source share

While most responses reinitialize the object in two steps; firstly, creating the source object, and then creating another object and replacing it with the first one using placement new ; this answer covers the case when you first create a pointer to an empty object, and then select and construct it:

 class c *c_instance; // Pointer to class c c_instance = new c(arg1, ..., argn) // Allocate memory & call the proper constructor // Use the instance eg c->data delete c_instance; // Deallocate memory & call the destructor 
0
Jun 28 '19 at 16:04 on
source share



All Articles