对于朋友类,enable_shared_from_this

时间:2017-02-17 15:37:32

标签: c++ shared-ptr friend

我有一个私人ctor课程,只能通过朋友课使用create方法构建:

class B {
    friend class A;
private:
    B(A* parent) { m_parent = parent; };

    A* m_parent;
};

class A {
public:
    A* createB() { return new B( this ); };
};

我希望createB将shared_ptr返回给B.我目前正在以这种方式解决它:

std::shared_ptr<B>
A::createB( A* parent )
{
    return std::shared_ptr<B>( new B( this ) );
}

但是因为对于继承的类有std :: enable_shared_from_this,我的解决方案被声明为坏样式,所以我想要求更好的解决方案。

感谢。

1 个答案:

答案 0 :(得分:1)

我可以看到enable_shared_from_this在您的示例中可能发挥作用的唯一方案是B::m_parent类型为std::shared_ptr<A>而不是A*

#include <memory>
class B {
    friend class A;
private:
    B(std::shared_ptr<A> && parent) : m_parent(std::move(parent)) {}

    std::shared_ptr<A> m_parent;
};

在这种情况下,createB必须传递shared_ptr<A>,但您不能简单地使用shared_ptr<A>(this)。这会导致在this被销毁时删除shared_ptr,但您自己并未分配this。这就是你想要做的事情,这是极不可能的。例如,如果this由现有shared_ptr<A>管理,那么您将有两个彼此不了解的shared_ptr<A>,他们最终都会尝试{{1}相同的实例。使用delete,您可以获得管理enable_shared_from_this的实际shared_ptr<A>的副本,以便他们彼此了解(他们共享参考计数器)。

this

如果已存在要复制的class A : std::enable_shared_from_this<A> { public: std::shared_ptr<B> createB() { return std::shared_ptr<B>(new B(shared_from_this())); }; }; ,则此可以正常工作。例如,这将是shared_ptr<A>的有效用法。

A::createB

这是 int main() { auto my_A = std::make_shared<A>(); auto my_B = my_A->createB(); return 0; } 的有效使用。您将获得A::createB例外。

std::bad_weak_ptr

请注意,在int main() { A my_A; auto my_B = my_A.createB(); return 0; } 行中,我没有像之前建议的那样使用return std::shared_ptr<B>(new B(shared_from_this()));std::make_shared<B>和非公开构造函数不兼容,您需要一个不是原始问题的解决方法。有关详细信息,请参阅this question