[英]How do i correctly add shared_pointers to probably derived classes into a std::vector?
我基本上有这个设置:
class B { /* ... */};
class C1 : public B { /* ... */};
class C2 : public B { /* ... */};
class X
{
std::vector<shared_ptr<B>> m_vec;
void addToVector(B* b);
}
addToVector
无法知道从B派生出多少个类,因此不必在意。 它将被这样称呼:
someFunction() {
C1 tmp;
/* do something with tmp */
m_myX.addToVector(&tmp);
}
因此,在someFunction
的末尾,tmp超出范围,将被删除。 addToVector
必须将一个shared_ptr addToVector
回一个tmp的副本到向量中,但是它怎么做呢?
void X::addToVector(B* b)
{
int i = sizeof(b); // allways sizeof(B) :(
shared_ptr<B> np(b);
m_vec.push_back(np); // garbage collected after calling fn returns :(
}
它应该做的是:
我怎样才能做到这一点?
您正在堆栈上创建一个对象,然后将其地址提供给shared_ptr
,它将尝试delete
堆栈上的对象,这是未定义的行为。
解决方案是停止这样做:
void someFunction() {
C1* c = new C1;
/* do something with *c */
m_myX.addToVector(c);
}
现在,您在堆上有了一个对象,该对象可以由shared_ptr
拥有。 无需复制它。
这只有在B
具有虚拟析构函数的情况下才能正常工作,但是可以通过首先创建一个shared_ptr来避免(并使代码更安全更整洁):
void someFunction() {
auto c = std::make_shared<C1>();
/* do something with *c */
m_myX.addToVector(c);
}
void X::addToVector(std::shared_ptr<B> b)
{
m_vec.push_back(np);
}
现在,堆对象一创建就由shared_ptr
管理,然后安全地存储在向量中。
您的“ someFunction”看起来很奇怪...(为什么不首先将tmp
创建为shared_ptr
?)
要使其工作,您将必须创建“虚拟构造函数”-在B* deepCopy() const
添加虚拟方法B* deepCopy() const
,并在所有子类中实现它,它的主体应基于以下模式: { return new DerivedType(*this); }
{ return new DerivedType(*this); }
如果您想保持干净,请使deepCopy
返回shared_ptr
并使用make_shared
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.