C++ 从指向的对象内重新分配共享\u ptr

C++ 从指向的对象内重新分配共享\u ptr,c++,shared-ptr,self-reference,C++,Shared Ptr,Self Reference,考虑以下代码 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_sha

考虑以下代码

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
在任何情况下都应该是安全的,不是吗?此代码中的额外复制是性能问题吗


编辑。在Chris回答之后,我看了一下,它允许以下替代实现

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();
struct base:std::从\u中启用\u共享\u{
虚拟std::shared_ptr bar()=0;
};
结构foo1:base{/*…*/};
结构foo2:base{
std::共享的测试条()
{
auto obj=从_this()共享的_;
如果(某些条件)
obj=std::使_共享();
// ...
返回obj;
}
};
std::shared_ptr x=std::make_shared();
x=x->bar();

正如此链接所指出的,在方法中删除此是安全的,即使有点混乱

我认为额外的复印不是问题。为了确保您必须进行配置文件。如果没有评测信息,如果是我,我更喜欢第二种方法而不是第一种b/c方法,这对程序员来说更容易理解,但主要是观点


如果您想让对象更简单地操作指向自身的共享指针等,您可能还想查看C++11中的
共享\u from\u this
模板。

感谢您提醒我
共享\u from\u this
。请查看我编辑的问题,也就是说,使用
shared\u from\u this
——这就是我们应该如何使用它的代码吗?当然,我想更简单的可能是
如果(某个条件){return std::make_shared()}或者{return shared\u from\u 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();