Wie Sie wissen, ist es nicht möglich, das Paar std :: enable_shared_from_this und shared_from_this() aus dem Konstruktor eines Objekts zu verwenden, da ein shared_pointer, der die Klasse enthält, noch nicht existiert. Allerdings würde mir diese Funktionalität wirklich gefallen. Ich habe mein eigenes System versucht und es scheint OK zu funktionieren.Verwenden von shared_from_this() im Konstruktor
namespace kp
{
template <class T>
void construct_deleter(T *t)
{
if(!t->_construct_pself)
{
t->~T();
}
free(t);
}
template <class T, typename... Params>
std::shared_ptr<T> make_shared(Params&&... args)
{
std::shared_ptr<T> rtn;
T *t = (T *)calloc(1, sizeof(T));
t->_construct_pself = &rtn;
rtn.reset(t, construct_deleter<T>);
t = new(t) T(std::forward<Params>(args)...);
t->_construct_pself = NULL;
t->_construct_self = rtn;
return rtn;
}
template <class T>
class enable_shared_from_this
{
public:
std::shared_ptr<T> *_construct_pself;
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this()
{
if(_construct_pself)
{
return *_construct_pself;
}
else
{
return _construct_self.lock();
}
}
};
}
Kann jemand irgendwelche Fehler in dieser Logik entdecken? Ich benutze im Grunde die Platzierung neu, um einen Zeiger auf die shared_ptr innerhalb der Klasse zuzuweisen, bevor der Konstruktor aufruft.
Wie es aussieht kann ich es als so verwenden:
std::shared_ptr<Employee> emp = kp::make_shared<Employee>("Karsten", 30);
und in dem Employee-Konstruktor:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
}
Bevor ich dies zu einer relativ großen Code-Basis verpflichten, würde ich wirklich zu schätzen einige Ideen oder Feedback von euch.
Danke!
Sie können diese nur über Ihre benutzerdefinierte 'make_shared' erstellen; Wenn Sie versuchen, eine andere Form der Initialisierung zu verwenden, wird es zur Laufzeit fehlschlagen. Verwenden Sie einfach das Standardmuster der Bereitstellung einer statischen 'create()' -Funktion, die eine Instanz erstellt, und führt dann alle Operationen aus, die 'shared_from_this()' erfordern, bevor Sie sie zurückgeben. –
Es tut mir leid, aber es gibt keine Möglichkeit, dass diese Art von Code in meinem Team überprüft wird. Können Sie nicht ein einfacheres und selbstdokumentierendes Design entwickeln? Was ist das Problem, das Sie wirklich zu lösen versuchen, und warum erfüllen konventionelle Ansätze dieses Ziel nicht? –