似乎std::unique_ptr
解决了一个问题,也可以通过移动语义来解决,即转移独资资源的所有权。以下是他们似乎执行相同工作的一些示例:
class SomeResource { /* resourcey stuff */ };
void ProcessResourcePtr(std::unique_ptr<SomeResource> r) { /* do stuff */ }
void ProcessResourceRvalRef(SomeResource&& r) { /* do stuff */ }
class OwnerOfResourcePtr {
private:
std::unique_ptr<SomeResource> r_;
public:
OwnerOfResourcePtr(std::unique_ptr<SomeResource> r) : r_(std::move(r)) { }
};
class OwnerOfResourceRvalRef {
private:
SomeResource r_;
public:
OwnerOfResourceRvalRef(SomeResource&& r) : r_(std::move(r)) { }
};
int main()
{
// transfer ownership to function via unique_ptr
std::unique_ptr<SomeResource> r1(new SomeResource());
ProcessResourcePtr(std::move(r1));
// transfer ownership to function via rvalue ref
SomeResource r2;
ProcessResourceRvalRef(std::move(r2));
// transfer ownership to instance via unique_ptr
std::unique_ptr<SomeResource> r3(new SomeResource());
OwnerOfResourcePtr(std::move(r3));
// transfer ownership to instance via rvalue ref
SomeResource r4;
OwnerOfResourceRvalRef(std::move(r4));
return 0;
}
就我而言,这些都以稍微不同的方式解决了几乎完全相同的问题。我不是100%清楚单向与对方的优势。我知道指针移动可能比移动构造函数/赋值更快,尽管通常认为两者都非常有效。我也知道移动语义允许你将数据保存在堆栈上(参见r2,r4),而不是要求使用new / malloc / etc(参见r1,r3)进行堆分配/释放,我认为好事(是吗?)。
一般情况下,何时应该更喜欢unique_ptr
移动语义,反之亦然?是否有任何用例只能由一个或另一个解决?
答案 0 :(得分:3)
如果你有一个没有移动构造函数的类(可能由其他人编写),甚至可能不是复制构造函数,那么你可能必须使用unique_ptr
。
如果某个实例是可选的,即可能不存在,则应使用unique_ptr
。
如果只能在调用构造函数后初始化对象,并且该对象不是默认构造的,则必须延迟构造,并且可以使用unique_ptr
。
即使一个类有一个移动构造函数,这可能比移动单个指针更昂贵。例如,如果该类包含许多POD实例或数组。