C++智能指针unique_ptr


struct B {
    virtual void bar() { std::cout << "B::bar\n"; }
    virtual ~B() = default;
};
struct D : B {
    D() { std::cout << "D::D\n"; }
    ~D() { std::cout << "D::~D\n"; }
    void bar() override { std::cout << "D::bar\n"; }
};

std::unique_ptr<B> p = std::make_unique<D>();
p->bar(); // 虚派发
// unique_ptr 能存储于容器
std::vector<std::unique_ptr<B>> v;
v.push_back(std::make_unique<D>());
v.push_back(std::move(p));
v.emplace_back(new D);

首先来一个简单的例子:创建一个unique_ptr,将其存放在一个容器中。作为一个unique_ptr的新手,你可能写出下面的代码:
std::unique_ptr<foo> q( new foo(42) );
v.push_back( q );
这似乎是合理的,但是这样做会让我进入一个灰色地带:谁是这个指针的拥有者,这个容器会在它生命周期的某个时刻释放该指针吗?或者是还得由创建者来自己释放它?
面对这些纠结,unique_ptr 禁止这样的代码。编译这样的代码将会导致编译错误。
Anyway,这里的问题就是我们只允许有该指针的一份拷贝。如果你想要将该对象交给另一个对象,就必须调用move函数,也就是说你必须放弃掉该对象的拥有权。
如:
v.push_back( std::move(q) );
执行完上述语句之后,q已经变成空的了,因为q已经放弃了该对象的拥有权,将拥有权交给了容器。
move语意可以用在任何你需要创建一个“右值引用”的地方。例如下面的代码:
return q;
返回一个unique_ptr则不需要任何特殊的代码就可以完成。
还有,创建一个临时的对象给一个需要unique_ptr的函数也是不需要特殊处理的。如:
process( std::unique_ptr<foo>( new foo(41) ) );

C++进阶:智能指针之unique_ptr(页面中有智能指针对象初始化时用的{}是不对的,用小括号)

C++11-unique_ptr详解

 
喜欢 0
分享