Shortest and best way to “reinitialize”/clean a class instance

后端 未结 5 1820
感动是毒
感动是毒 2021-01-02 01:56

I will keep it short and just show you a code example:

class myClass
{
public:
  myClass();
  int a;
  int b;
  int c;
}

// In the myClass.cpp or whatever
m         


        
相关标签:
5条回答
  • 2021-01-02 02:10

    You can implement clear as a generic function for any swappable type. (A type being swappable is common and done implicitly in C++0x with a move constructor. If you have a copy constructor and assignment operator that behave appropriately, then your type is automatically swappable in current C++. You can customize swapping for your types easily, too.)

    template<class C>
    C& clear(C& container) {
      C empty;
      using std::swap;
      swap(empty, container);
      return container;
    }
    

    This requires the least work from you, even though it may appear slightly more complicated, because it only has to be done once and then works just about everywhere. It uses the empty-swap idiom to account for classes (such as std::vector) which don't clear everything on assignment.


    If you have seen that the swap is a performance bottleneck (which would be rare), specialize it (without having to change any use of clear!) in myClass's header:

    template<>
    myClass& clear<myClass>(myClass& container) {
      container = myClass();
      return container;
    }
    

    If myClass is a template, you cannot partially specialize clear, but you can overload it (again in the class header):

    template<class T>
    myClass<T>& clear(myClass<T>& container) {
      container = myClass<T>();
      return container;
    }
    

    The reason to define such specialization or overload in myClass's header is to make it easy to avoid violating the ODR by having them available in one place and not in another. (I.e. they are always available if myClass is available.)

    0 讨论(0)
  • 2021-01-02 02:19

    You may want to consider using placement new. This will allow you to use the same memory but call the constructor again.

    Don't forget to call the destructor before using placement new, however.

    0 讨论(0)
  • 2021-01-02 02:21
    myUsedInstance = myClass();
    

    C++11 is very efficient if you use this form; the move assignment operator will take care of manually cleaning each member.

    0 讨论(0)
  • 2021-01-02 02:27

    Well, there is a much much more elegant way: Create a vector of your classes with single element and update that element calling the constructor:

    std::vector<your_class> YourClasses;
    YourClasses.resize(1);
    YourClasses[0] = YourClass(...);
    
    YourClass &y_c = *(&YourClasses[0]);
    // do whatever you do with y_c
    // and then if you want to re-initialize, do this
    YourClasses[0] = YourClass(...);
    // and voilla, continue working with resetted y_c
    
    0 讨论(0)
  • 2021-01-02 02:28

    Just assign to a default-constructed class, like you have. Just use a temporary, though:

    struct foo
    {
        int a, b, c;
    
        foo() :
        a(), b(), c()
        {} // use initializer lists
    };
    
    foo f;
    f.a = f.b =f.c = 1;
    
    f = foo(); // reset
    
    0 讨论(0)
提交回复
热议问题