【发布时间】:2015-09-07 16:28:41
【问题描述】:
考虑下面的代码
struct base {
virtual void bar(std::shared_ptr<base>&) = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
void bar(std::shared_ptr<base>&obj)
{
// ...
if(some_condition)
obj = std::make_shared<foo1>(); // re-assign obj
// ...
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x->bar(x); // last line
这段代码会唤起 UB 吗? (注意:从最后一行调用时,重新分配 obj 将破坏调用 foo2::bar 的 this 对象)。如果之后没有访问bar的数据,代码还可以吗?
另一种编码方式是
struct base {
virtual std::shared_ptr<base> bar(std::shared_ptr<base>) = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
std::shared_ptr<base> bar(std::shared_ptr<base> obj)
{
// ...
if(some_condition)
obj = std::make_shared<foo1>();
// ...
return obj;
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x=x->bar(x);
在任何情况下都应该是安全的,不是吗?此代码中的额外复制是否存在性能问题?
编辑。克里斯回答后,我查看了shared_from_this,它允许以下替代实现
struct base : std::enable_shared_from_this<base> {
virtual std::shared_ptr<base> bar() = 0;
};
struct foo1 : base { /* ... */ };
struct foo2 : base {
std::shared_ptr<base> bar()
{
auto obj = shared_from_this();
if(some_condition)
obj = std::make_shared<foo1>();
// ...
return obj;
}
};
std::shared_ptr<base> x = std::make_shared<foo2>();
x=x->bar();
【问题讨论】:
标签: c++ shared-ptr self-reference