std :: shared_ptr, вызывающий проблемы при копировании объектов

0

У меня есть класс, который имеет член shared_ptr. Конструктор этого класса принимает объект shared_ptr который присваивается его члену. Теперь проблема в том, что если я назначу этот объект другому объекту того же класса, оба указывают на тот же shared_ptr. И я не хочу этого делать. Вот код, который похож на код, который у меня есть, но когда я выполняю задание, он сбрасывается при обмене shared_ptr. Пожалуйста, помогите мне сделать это так, как я хочу.

Если вы выполняете строку obj2 = * obj1, вы можете видеть, что новый shared_ptr создается в конструкторе, а затем происходит вызов назначения, когда swap получает temp shared_ptr на rhs и заканчивает рекурсивно убивая стек.

class A
{
public:
virtual ~A(){};
virtual void Test()
{
}
int i;
int j;
};

class C:public A
{
public:

void Test()
{
}

};


class B
{
 public:
B::B(const B& rhs) : m_Command(std::make_shared<A>(*rhs.m_Command)) 
{


}
B::B(B&& rhs) : m_Command(std::move(rhs.m_Command)) 
{

}
B& B::operator=(B rhs) 
{
    std::swap(*this, rhs);
    return *this;
}

B()
{

}

B(std::shared_ptr<A> command)
{
    m_Command=command;
}
void Test()
{

}
std::shared_ptr<A> m_Command;
};

int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<A> cmd(new C());
B *obj1=new B(cmd);
B obj2;
obj2=*obj1;
cmd->i=10;
cmd->j=20;



return 0;
}
  • 5
    Если вы содержите A в B (состав), почему вы также выводите B из A ? Если у B есть отношения is-a и has-a с A , у вашего дизайна, вероятно, есть проблема. И вы нарушаете Правило 3 .
  • 2
    Ваш вызов std::swap бесконечно рекурсивен и вызывает StackOverflow (!). Смотрите это , это , это , это и это
Показать ещё 1 комментарий
Теги:
c++11

1 ответ

1
Лучший ответ

std::make_shared<A>(*rhs.m_Command) будет терпеть неудачу, если rhs.m_Command имеет значение null.

  • 0
    Какие изменения мне нужно сделать, чтобы он работал в приведенном выше коде?
  • 0
    Ну, вы могли бы мелко скопировать B Или вы можете инициализировать m_Command только в конструкторе копирования, если rhs.m_Command равен NULL. Или вы можете убедиться, что все B имеют ненулевое значение m_Command . Или вы можете удалить весь ваш код и заменить его на «hello world». Любая из этих вещей может привести к тому, что ваш код не потерпит крах или произойдет сбой другим способом.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню