在使用移动 unique_ptr 到同一对象构造基类后,使用指向对象的原始指针初始化字段

Naj*_*aju 3 c++ smart-pointers c++11

我有一个对象,没有其他人Foo拥有Owner。我创建了一个Derived继承的类的对象Owner,将它传递unique_ptr给新创建的Foo. Derived有一个类的成员User也需要使用Foo,但不拥有它,所以它只得到一个指向它的原始指针。

#include <memory>
#include <iostream>
using namespace std;

struct Foo {
  void talk() { cout << "foo" << endl; }
};

struct User {
  Foo *foo;
  User(Foo *_foo): foo(_foo) {};
  void use() { foo->talk(); } //potential disaster if foo's memory has changed
};

struct Owner {
  unique_ptr<Foo> foo;
  Owner(unique_ptr<Foo> _foo): foo(move(_foo)) {};
};

struct Derived : public Owner {
  User user;
  Derived(unique_ptr<Foo> _foo)
  : Owner {move(_foo)},
    user{_foo.get()}  //potential disaster: _foo has already been move()'d, can't get()!
  {};
  void use() { user.use(); };
};

int main() {
  Derived d(make_unique<Foo>());
  //do other stuff
  d.use();  //potential disaster
}
Run Code Online (Sandbox Code Playgroud)

问题是,在初始化列表Derived,我需要move()Foo将它传递给Owner的构造函数(这需要一个unique_ptr<Foo>,因为它是拥有者),也是一个原始指针传递给FooUser。但是User当初始化时,unique_ptr<Foo>已经被移动并且foo.get()可能指向一个无效的位置!

确保User获得有效(非拥有)指针FooOwner仍然获得其的好方法是什么unique_ptr<Foo>

Tim*_*imo 5

您可以保护基类的成员(或一些更高的可访问性)并引用基类成员

Derived(unique_ptr<Foo> _foo)
  : Owner {move(_foo)},
    user{foo.get()} // refers to Owner::foo
Run Code Online (Sandbox Code Playgroud)