我有一个实现接口(Geometry
)的类(LinkList
)。我的示例底部的代码显然是错误的,所以我正在考虑实现std::enable_shared_from_this
。可以Geometry
安全地继承std::enable_shared_from_this<LinkList>
,我可以安全地将getLinkList()
方法更改为shared_from_this()
吗?如果我的Geometry
类有多个继承的接口会发生什么,我可以为所有接口执行此操作吗?
class Link
{
public:
std::string getName() { return "the name"; }
};
class LinkList
{
public:
virtual Link* getLink(int id) = 0;
virtual int size() = 0;
};
class Geometry : LinkList
{
private:
int state;
public:
void doSomething() { state = 1; }
virtual Link* getLink(int id) { return new Link(); }
virtual int size() { return 1; }
std::shared_ptr<LinkList> getLinkList() { return std::shared_ptr<LinkList>(this); }
};
void printList(std::shared_ptr<LinkList> linkList)
{
for (int i = 0; i < linkList->size(); i++)
{
std::cout << linkList->getLink(i)->getName() << std::endl;
}
}
void main()
{
Geometry* geom = new Geometry();
printList(geom->getLinkList());
geom->doSomething(); // Error here
}
答案 0 :(得分:3)
我示例底部的代码显然是错误的
代码没有明显错误,该错误位于getLinkedList
,它将this
的所有权授予shared_ptr
,导致printList
返回时删除Geometry
最后一个shared_ptr对象超出范围。因此,该示例的最后一行显然是非常错误的,因为前一行巧妙地删除了该对象。
std::enable_shared_from_this<LinkList>
可以安全地继承getLinkList()
是的,它只是一个基类。从它继承几乎总是安全的(这并不意味着你可以安全地使用它!)
我可以安全地将
shared_from_this()
方法更改为Geometry
吗?
仅当shared_ptr
对象归Geometry* geom = new Geometry();
所有,并且在您的代码中,它不是:
shared_ptr
您需要将指针存储在enable_shared_from_this
(创建它时最好立即),以使auto geom = std::make_shared<Geometry>();
printList(geom->shared_from_this());
geom->doSomething();
基类可用,所以这应该没问题:
shared_from_this()
(当然使用printList(geom)
在那里毫无意义,因为你已经拥有了sahred_ptr并且只能Geometry
}。
如果我的
enable_shared_from_this
类有多个继承的接口会发生什么,我可以为所有接口执行此操作吗?
不,如果该类有多个shared_ptr
基类,则enable_shared_from_this
构造函数不知道要初始化哪一个。我认为你会因为含糊不清而收到错误,或者如果不是weak_ptr
基类都会导致空Geometry
使它们变得无用。
<强>更新强>:
您可以enable_shared_from_this<Geometry>
从[{1}}(不是来自enable_shared_from_this<LinkList>
而不是来自每个界面)派生shared_ptr<LinkList> Geometry::getLinkList()
{
return shared_from_this();
}
,并定义:
shared_from_this()
shared_ptr<LinkList>
返回的对象将隐式转换为this
。首先,您仍然需要shared_ptr
拥有{{1}}。