2016-05-27 7 views
0

Ich habe einen Code wie den folgendenPassing Shared_ptr dieses in Konstruktor

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(); 
} 

Wenn ich es laufen bekomme ich ein

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

von diesem question Ich habe, dass ich nicht shared_from_this(), bis das Objekt aufrufen kann ist vollständig aufgebaut. Ich denke, das bedeutet, dass ich keine Objekte vom Typ Attribute im Konstruktor erstellen kann, aber ich sollte sie instanziieren, nachdem der Konstruktor endet.

Wissen Sie, ob es ein Weg ist, dieses Problem zu lösen, denn es wäre wirklich ärgerlich für mich, die Attribute-Objekte, die nicht im Konstruktor sind, instanziieren zu müssen.

+0

Wird das 'Task'-Objekt von' std :: shared_ptr' verwaltet? – LogicStuff

+0

Warum können Sie 'task' nicht als' const std :: shared_ptr & 'an Ihren Konstruktor übergeben? – GeorgeAl

Antwort

1

Ich glaube, Sie Foul dieser Regeln sind fallen, wie pro this:

Beachten Sie, dass vor shared_from_this auf einem Objekt t zu nennen, muss es ein std :: shared_ptr, die t besitzt.

Sie scheinen eine seltsame Besitz Beziehung zwischen Task und Attribute zu haben, die Sie möglicherweise zu überdenken (wenn ein Task seine Attributes besitzt, warum sie shared_ptr s auf ihre Task brauchen?).

+0

Ich denke, du hast Recht, ich nehme an, ich bin gerade durch eine intelligente Zeiger-Raserei gegangen! – user2046258

1

Da die Taskbesitzt die Attribute s, die Attribute s brauchen nicht Eigentum zu teilen mit dem Task - sie müssen sich keine Sorgen über die Task outliving. Sie können nur rohe Zeiger verwenden:

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

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

Oder, wenn Sie die semantischen mehr explizit, observer_ptr<Task> zum Ausdruck bringen wollen.

Beachten Sie, dass Sie eine Kopie/Verschiebung Konstruktoren/Zuweisungsoperatoren für Task haben müssen, die die Attribute korrekt zuweisen, um auf die neue Task anstelle der alten zu zeigen.

Verwandte Themen