enable_shared_from_this 给朋友 class
enable_shared_from_this for friend class
我有一个 class 和一个私有构造函数,只能由朋友 class 使用创建方法构造:
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 代替 return a shared_ptr 到 B。我目前是这样解决的:
std::shared_ptr<B>
A::createB( A* parent )
{
return std::shared_ptr<B>( new B( this ) );
}
但是由于 std::enable_shared_from_this 继承 classes 我的解决方案被声明为糟糕的风格我想寻求更好的解决方案。
谢谢。
我能看到 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>
彼此不认识,他们最终都会尝试 delete
同一个实例。使用 enable_shared_from_this
可以让您获得管理 this
的实际 shared_ptr<A>
的副本,以便它们彼此了解(它们共享一个引用计数器)。
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>
。 std::make_shared
和 non-public 构造函数不兼容,您需要一个不属于原始问题的解决方法。有关详细信息,请参阅 this question。
我有一个 class 和一个私有构造函数,只能由朋友 class 使用创建方法构造:
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 代替 return a shared_ptr 到 B。我目前是这样解决的:
std::shared_ptr<B>
A::createB( A* parent )
{
return std::shared_ptr<B>( new B( this ) );
}
但是由于 std::enable_shared_from_this 继承 classes 我的解决方案被声明为糟糕的风格我想寻求更好的解决方案。
谢谢。
我能看到 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>
彼此不认识,他们最终都会尝试 delete
同一个实例。使用 enable_shared_from_this
可以让您获得管理 this
的实际 shared_ptr<A>
的副本,以便它们彼此了解(它们共享一个引用计数器)。
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>
。 std::make_shared
和 non-public 构造函数不兼容,您需要一个不属于原始问题的解决方法。有关详细信息,请参阅 this question。