2017-01-10 2 views
1

У меня возникла проблема с вызовом деструктора класса дважды, когда я создаю общий ptr для моего класса.Деструктор класса, вызываемый дважды при создании shared_ptr

Я пытаюсь создать вектор объектов, и каждый объект имеет конструктор и деструктор.

Когда я делаю вызов, такие как:

std::vector<std::shared_ptr<ServoController>> servos; 
bool CreateServo(int id) 
{ 
    std::shared_ptr<ServoController> servo = std::make_shared<ServoController>(ServoController(id)); 
    servos.push_back(servo); 
} 

Конструктор сервоконтроллер называется, а затем сразу же Разрушитель для сервоконтроллер называется, перед этим функция push_back даже называется.

Затем, когда я закрываю приложение, деструктор для ServoController вызывается снова. Но конструктор только назывался один раз до сих пор (у меня только 1 объект в векторе). Должно ли, по крайней мере, заставить конструктора работать снова?

Есть ли способ сделать вектор моего класса, и для каждого объекта в векторе конструктор должен вызываться один раз, а деструктор должен вызываться один раз, когда объекты удаляются из вектора или вектора разрушается?

Спасибо, -D

ответ

11

Вы создаете временный объект с этим вызовом, который является то, что вызывает первый (неожиданный) деструктор вызов.

std::make_shared<ServoController>(ServoController(id)); 

Последовательность событий:

  • ServoController(id) создает новый временный объект, который передается в качестве аргумента std::make_shared.
  • std::make_shared<ServoController> затем переводит временный объект на ServoControllerкопия конструктора (что, вероятно, не то, что вы хотите). Вот почему ваш главный конструктор вызван только один раз.
  • Это создает новый объект в куче (управляемый shared_ptr), который является копией созданного вами временного.
  • Временный объект немедленно уничтожается, что является первым вызовом деструктора.

То, что вы на самом деле хотите это:

std::make_shared<ServoController>(id); 

std::make_shared направляет свои аргументы непосредственно конструктору для его аргумента шаблона. Вам не нужен дополнительный вызов конструктора.

+0

Это мог быть конструктор перемещения, который был вызван, в отличие от конструктора копирования. –

Смежные вопросы