基类构造函数中替代shared_from_this()的更优雅实现方案
问题:无需友元与Boost的优雅父子类工厂实现方案?
我之前写过这样的类结构:
#include <memory> #include <set> using namespace std; class Base : public enable_shared_from_this<Base> { public: explicit Base(Base *parent = nullptr) : parent(parent) { parent->children.insert(shared_from_this()); } private: Base *parent; // 实际想用弱指针 set<shared_ptr<Base>> children; };
有人指出构造函数里不能用shared_from_this(),这个结论是对的——因为此时对象还没被shared_ptr持有,调用会触发未定义行为。
我知道除了boost::intrusive_ptr之外,最优解是用静态工厂方法替代构造函数直接调用。但因为基类是虚基类,我先写出了这样的代码:
#include <memory> #include <set> using namespace std; class Base : public enable_shared_from_this<Base> { protected: Base() {}; void SetParent(Base *_parent) { parent = _parent; parent->children.insert(shared_from_this()); } private: Base *parent = nullptr; set<shared_ptr<Base>> children; }; class Derived : public Base { public: static Derived *Create(Base *parent = nullptr) { Derived *obj = new Derived(); if (parent) obj->SetParent(parent); return obj; } private: Derived() : Base() {}; };
但这种写法要求每个子类都重复写Create方法,太冗余了。于是我想到在基类里实现一个模板工厂方法,但为了强制子类必须通过工厂创建(把构造函数设为私有),不得不把基类声明为子类的友元,最终代码如下:
#include <memory> #include <set> using namespace std; class Base : public enable_shared_from_this<Base> { public: template<typename T> static T* Create(Base *parent = nullptr) { T *obj = new T(); if (parent) obj->SetParent(parent); return obj; } protected: Base() {}; void SetParent(Base *_parent) { parent = _parent; parent->children.insert(shared_from_this()); } private: Base *parent = nullptr; set<shared_ptr<Base>> children; }; class Derived : public Base { private: friend class Base; Derived() : Base() {}; };
现在想问:有没有更优雅的实现方式?最好更简洁,而且不需要用Boost和友元类?
内容的提问来源于stack exchange,提问作者traveh
相关产品推荐
相关产品推荐

