2017-01-16 2 views
0

Этого вопроса является продолжение вопросом этого вопроса здесь: original questionСамого содержащего shared_ptr из себя, что наследуется от станда :: enable_shared_from_this

У меня есть класс, который наследуется от std::enable_shared_from_this и этого класса содержит std::shared_ptr<Self>

В любом из конструкторов этого класса после того, как я узнаю, что детали класса полны и успешны, как я могу назначить сохраненный std::shared_ptr<Self> как номер shared this?

Пример:

class Self : public std::enable_shared_from_this<Self> { 
private: 
    std::shared_ptr<Self> me_; // Or 
    std::unique_ptr>Self> me_; 

public: 
    Self (/*some parameters*/); 
}; 

Self::Self(/* some parameters */) { 
    // Check parameters for creation 

    // Some work or initialization being done 

    // If all is successful and construction of this class is about 
    // to leave scope, then set the smart pointer to the this* 

    // How to do ... 
    me_ = std::enable_shared_from_this<Self>::shared_from_this(); 
    // Properly if this is even possible at all. 
} 
+0

@ Jason R oh okay then. Поэтому мне потребовалось бы иметь «класс типа менеджера», который содержит экземпляры, или мне нужно будет установить его в функции, которая будет вызываться сразу после его конструктора, например, в функции конструктора или инициализации. –

+0

a shared_ptr to self - оксюморон. полезно только для временного хранения объекта в живых (например, при ожидании обратного вызова). –

ответ

2

Вы не можете. В этот момент shared_ptr, который указывает на текущий экземпляр Self, пока не существует. Он не может существовать до тех пор, пока конструктор не вернется. shared_from_this() имеет предварительное условие, что shared_ptr уже существует, что указывает на this.

+0

Хорошо, что имеет смысл. Поэтому мне нужен либо класс менеджера, содержащий общие указатели, либо метод в этом классе, который должен быть вызван после конструктора, например метода create() или init(). –

+0

Да, это так. –

+0

Да, наследство от этой части библиотеки для меня нова. –

1

Вы не можете, потому что вы должны быть существующим std::shared_ptr, который указывает на текущий объект. Как говорит Скотт Мейерс в современных эффективных C++ (глава 19), можно объявлять конструкторы частных, и сделать фабричную функцию возвращения std::shared_ptr, как:

class Self: public std::enable_shared_from_this<Self> { 
public: 
// factory function that perfect-forwards args 
// to a private ctor 
    template<typename... Ts> 
    static std::shared_ptr<Self> create(Ts&&... params); 
    ... 
    void process(); 
    ... 
private: 
    ... // ctors 
}; 

, а затем вызвать process, что может быть что-то вроде:

void Self::process() 
{ 
    ... 
    me_ = shared_from_this(); 
} 
+0

Я думаю, что это технически возможно (хотя может быть плохой дизайн). См. Мой комментарий к JasonR [ответ] (http://stackoverflow.com/a/41683759/3246555). – AlexD

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