Прежде всего, emplace_back
создает объект на месте, пересылая его аргументы. Итак, в конечном итоге вы вызываете конструктор копирования вашего класса с аргументом *this
.
Я пытаюсь придумать случай, когда необходимо добавить объекты в список внутри конструктора, и мне трудно. Я думаю, что есть лучшие альтернативы.
Поместите его в список вне конструктора
Просто создайте его следующим образом.
myclassobjects.emplace_back(/*constructor params*/);
В С++ 17 это даже возвращает ссылку на вновь созданный объект.
MyClass& myclass_ref = myclassobjects.emplace_back(/*constructor params*/);
do_something_with_my_class_object(myclass_ref);
Это самый чистый и эффективный способ сделать это. Дополнительным преимуществом является то, что вы можете создавать локальные объекты, не добавляя их в список, если это необходимо.
Используйте фабричный метод, который добавляет его в список
Если вам абсолютно необходимо иметь каждый объект в списке и вы не хотите, чтобы он был копией, используйте статический фабричный метод. Если список и вызываемый объект должны совместно владеть, вы можете использовать список std::shared_ptr
и сделать следующее.
MyClass {
private:
MyClass(); // private constructor forbids on the stack variables
public:
static std::shared_ptr<MyClass> create_instance() {
auto ptr = make_shared<MyClass>(); // We can access the constructor here
myclass_objects.emplace_back(ptr);
return ptr;
}
}
С другой стороны, если ваш список гарантированно переживет обработчик вызываемого объекта, более целесообразно иметь список std::unique_ptr
, которые содержат объекты и возвращают ссылки на них.
MyClass {
private:
MyClass(); // private constructor forbids on the stack variables
public:
// pre C++17
static MyClass& create_instance() {
auto ptr = make_unique<MyClass>();
auto& ref = *ptr; // Store ref before we move pointer
myclass_objects.emplace_back(std::move(ptr));
return ref;
}
// C++17
static MyClass& create_instance() {
auto ptr = make_unique<MyClass>();
return *(myclass_objects.emplace_back(std::move(ptr)));
}
}
Конечно, эти примеры охватывают только конструкторы по умолчанию. Поскольку вам обычно приходится работать с большим количеством конструкторов, вам, вероятно, понадобится шаблонный create_instance
, который перенаправляет свои аргументы конструктору.
person
patatahooligan
schedule
28.09.2017
*this
. Я думаю, ты этого не хочешь. - person StoryTeller - Unslander Monica   schedule 28.09.2017myclassobjects.push_back(*this)
. т.е. он создает копию текущего объекта и добавляет ее в конец списка. - person Some programmer dude   schedule 28.09.2017