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

时间:2010-04-18 21:26:40

标签: 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;
}

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

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

我想出了这样的方式:

myClass emptyInstance;
myUsedInstance = emptyInstance; // Ewww.. code smell?

或..

myUsedInstance.a = 0; myUsedInstance.c = 0; myUsedInstance.c = 0; 
  • 我想你知道我想要什么,有没有更好的方法来实现这个目标?

5 个答案:

答案 0 :(得分:19)

myUsedInstance = myClass();

如果您使用此表单,C ++ 11非常有效;移动分配操作员将负责手动清理每个成员。

答案 1 :(得分:7)

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

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

这需要您的工作量最少,即使它可能看起来稍微复杂一些,因为它只需要完成一次,然后就可以在任何地方使用。它使用空交换成语来解释类(例如 std :: vector ),它们不会清除任务中的所有内容。


如果您已经看到交换是性能瓶颈(这种情况很少见),请将其专门化(,而不必更改清除的任何使用) em> myClass 的标题:

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

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

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

myClass 的标题中定义此类特化或重载的原因是,通过让它们在一个地方而不是另一个地方可用,可以轻松避免违反ODR。 (即,如果 myClass 可用,它们始终可用。)

答案 2 :(得分:4)

只需像你一样分配给默认构造的类。只是使用一个临时的,但是:

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

答案 3 :(得分:-1)

您可能需要考虑使用展示位置新功能。这将允许您使用相同的内存,但再次调用构造函数。

不要忘记在使用placement new之前调用析构函数。

答案 4 :(得分:-1)

嗯,还有一种更为优雅的方法: 使用单个元素创建类的向量,并更新该元素,调用 构造函数:

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