2016-05-27 6 views
0

У меня есть код, подобный следующемуПередача shared_ptr этого в конструкторе

class Task; 

class Attribute 
{ 
public: 
    Attribute(Task* task, std::string name); 

    std::shared_ptr<Task> task_; 
    std::string name_; 
}; 

class Task : std::enable_shared_from_this<Task> 
{ 
public: 
    std::shared_ptr<Task> getSharedPtr() 
    { 
     return this->shared_from_this(); 
    } 

    Attribute att1_ = {this, "attribute1"}; 
    Attribute att2_ = {this, "attribute2"}; 
}; 

Attribute::Attribute(Task* task, std::string name) 
    : name_(name) 
{ 
    task_ = task->getSharedPtr(); 
} 

Когда я запускаю его я получаю

$ terminate called after throwing an instance of 'std::bad_weak_ptr' 

из этого question меня, что я не могу назвать shared_from_this() недо объекта полностью построена. Я предполагаю, что это означает, что я не могу создавать объекты типа Attribute в конструкторе, но я должен создать их после завершения конструктора.

Знаете ли вы, что это способ преодолеть эту проблему, потому что мне было бы очень неприятно создавать объекты атрибута не в конструкторе.

+0

Объект 'Task' управляется' std :: shared_ptr'? – LogicStuff

+0

Почему вы не можете передать 'task' как' const std :: shared_ptr & 'вашему конструктору? – GeorgeAl

ответ

1

Я думаю, что вы падаете в немилость этого правила, согласно this:

Обратите внимание, что перед вызовом shared_from_this на объекте т, должно стать станд :: shared_ptr, которому принадлежит т.

Вы, кажется, есть странные отношения собственности между Task и Attribute, которые вы можете захотеть пересмотреть (если Task владеет своей Attributes, почему они нуждаются shared_ptr с до их Task?).

+0

Я думаю, что ты прав, я полагаю, я просто прошел через умную указку! – user2046258

1

Поскольку Taskвладеет в Attribute s, то Attribute ей не нужно делить собственность с Task - они не должны беспокоиться о переживая в Task. Вы можете просто использовать сырые указатели:

class Attribute 
{ 
public: 
    Attribute(Task* task, std::string name); 

    Task* task_; 
    std::string name_; 
}; 

Или, если вы хотите, чтобы выразить семантическую более явно, observer_ptr<Task>.

Обратите внимание, что вам нужно будет иметь операции копирования/перемещения конструкторов/присваивания для Task, чтобы правильно переназначить атрибуты, чтобы указать на новый Task вместо старого.

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