Calling a constructor to re-initialize object

前端 未结 12 1712
执笔经年
执笔经年 2020-12-04 15:01

is it possible to re-initialize an object of a class using its constructor?

相关标签:
12条回答
  • 2020-12-04 15:46

    Literally? Yes, by using placement new. But first you have to destruct 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 value of this does not go beyond purely theoretical though. Don't do it in practice. The whole thing is ugly beyond description.

    0 讨论(0)
  • 2020-12-04 15:53

    It's possible, although it's a very bad idea. The reason why is that without calling the destructors on the existing object, you are going to leak resources.

    With that major caveat, if you insist on doing it, you can use placement new.

    // Construct the class
    CLASS cl(args);
    
    // And reconstruct it...
    new (&cl) CLASS(args);
    
    0 讨论(0)
  • 2020-12-04 15:55

    Short answer:

    No. If part of your object's intended behavior is to be initialized several times, then the best way to implement this is through an accessible initialization method. The constructor of your class can simply defer to this method.

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

    Nitpicker corner:

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

    0 讨论(0)
  • 2020-12-04 15:56

    No, constructors are only called when the object is first created. Write a new method to do it instead.

    Edit

    I will not acknowledge placement new, because I don't want to have to get a pet raptor for work.

    See this comic, but think of the topic on hand...

    0 讨论(0)
  • 2020-12-04 15:58

    Yes you can cheat and use placement new.
    Note: I do not advice this:

    #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.
    }
    
    0 讨论(0)
  • 2020-12-04 16:03

    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 having to maintain a bunch of Clear methods, and bugs that can easily go unnoticed if at some point the object changes, and the Clear method no longer matches the constructor.

    The above will work fine in most contexts, but fail horribly if the reference is to a base within a derived object that has a virtual destructor. For this reason, the above implementation prevents use with objects that have a virtual destructor.

    0 讨论(0)
提交回复
热议问题