Ответ 1
myUsedInstance = myClass();
С++ 11 очень эффективен, если вы используете эту форму; оператор назначения перемещения позаботится о том, чтобы вручную очистить каждый элемент.
Я буду держать его коротким и просто покажу вам пример кода:
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.
Я подошел так:
myClass emptyInstance;
myUsedInstance = emptyInstance; // Ewww.. code smell?
или..
myUsedInstance.a = 0; myUsedInstance.c = 0; myUsedInstance.c = 0;
myUsedInstance = myClass();
С++ 11 очень эффективен, если вы используете эту форму; оператор назначения перемещения позаботится о том, чтобы вручную очистить каждый элемент.
Вы можете реализовать clear в качестве общей функции для любого типа swappable. (Тип, подлежащий замене, является общим и выполняется неявно в С++ 0x с конструктором перемещения. Если у вас есть конструктор копирования и оператор присваивания, которые ведут себя надлежащим образом, тогда ваш тип автоматически заменяется в текущем С++. Вы можете также легко настраивать подкачку для ваших типов.)
template<class C>
C& clear(C& container) {
C empty;
using std::swap;
swap(empty, container);
return container;
}
Для этого требуется наименьшая работа от вас, хотя она может показаться несколько более сложной, потому что она должна выполняться только один раз, а затем работает практически везде. Он использует идиому с пустой заменой для учета классов (например, std::vector), которые не очищают все при назначении.
Если вы видели, что swap является узким местом производительности (что было бы редко), специализируйтесь на нем (не изменяя использование clear !) в заголовке 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, предоставляя их в одном месте, а не в другом. (I.e. они всегда доступны, если myClass доступен.)
Просто назначьте класс, построенный по умолчанию, как и у вас. Просто используйте временную, хотя:
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
Возможно, вы захотите рассмотреть возможность использования нового места размещения. Это позволит вам использовать одну и ту же память, но снова вызовет конструктор.
Однако не забудьте вызвать деструктор, прежде чем использовать новое место размещения.