"重新初始化"/清理类实例的最短和最佳方法

Ope*_*per 14 c++

我会简短地介绍一下代码示例:

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

// In the myClass.cpp or whatever
myClass::myClass( )
{
 a = 0;
 b = 0;
 c = 0;
}
Run Code Online (Sandbox Code Playgroud)

好的.如果我知道有一个myClass的实例并将一些随机垃圾设置为a,b和c.

  • 调用类构造函数后,将它们全部重置为状态的最佳方法是什么,所以:0,0和0?

我想出了这样的方式:

myClass emptyInstance;
myUsedInstance = emptyInstance; // Ewww.. code smell?
Run Code Online (Sandbox Code Playgroud)

要么..

myUsedInstance.a = 0; myUsedInstance.c = 0; myUsedInstance.c = 0; 
Run Code Online (Sandbox Code Playgroud)
  • 我想你知道我想要什么,有没有更好的方法来实现这一目标?

Goz*_*Goz 19

myUsedInstance = myClass();
Run Code Online (Sandbox Code Playgroud)

如果你使用这个表单,C++ 11非常有效; 移动分配操作员将负责手动清洁每个成员.

  • 现在,如果我想从里面做这件事怎么办?`*this = MyClass()`? (3认同)

小智 7

您可以将clear实现为任何可交换类型的通用函数.(可交换的类型是常见的,并且在C++ 0x中使用移动构造函数隐式完成.如果您有一个行为正确的复制构造函数和赋值运算符,那么您的类型可以在当前C++中自动交换.您可以为您的类型自定义交换也很容易.)

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

这需要你做的最少的工作,即使它可能看起来稍微复杂一些,因为它只需要做一次然后在任何地方工作.它使用空交换习惯用来计算类(例如std :: vector),它们不会清除赋值中的所有内容.


如果您已经看到交换是性能瓶颈(这种情况很少见),请在myClass的标头中专门化它(不必更改任何 clear的使用!):

template<>
myClass& clear<myClass>(myClass& container) {
  container = myClass();
  return container;
}
Run Code Online (Sandbox Code Playgroud)

如果myClass是一个模板,你不能部分专门清除,但你可以重载它(再次在类头中):

template<class T>
myClass<T>& clear(myClass<T>& container) {
  container = myClass<T>();
  return container;
}
Run Code Online (Sandbox Code Playgroud)

myClass的标题中定义这种特化或重载的原因是为了避免通过在一个地方而不是另一个地方提供ODR来避免违反ODR.(即如果myClass可用,它们总是可用的.)

  • 很好的答案.:) (2认同)