【发布时间】:2015-04-16 20:46:39
【问题描述】:
我有一个带有指针成员的基类。我必须做出有根据的猜测来确定它应该是unique_ptr 还是shared_ptr。它们似乎都不能解决我的特定用例。
class Base
{
public:
Base(): pInt(std::unique_ptr<int>(new int(10))) {};
virtual std::unique_ptr<int> get() = 0;
//Base(): pInt(std::shared_ptr<int>(new int(10))) {}; // Alternate implementation
//virtual std::shared_ptr<int> get() = 0; // Alternate implementation
private:
std::unique_ptr<int> pInt;
//std::shared_ptr<int> pInt; // Alternate implementation
};
基类已派生到Derived1 和Derived2。前者返回unique_ptr成员pInt,后者返回本地unique_ptr对象。
class Derived1: public Base
{
public:
Derived1() {};
virtual std::unique_ptr<int> get()
{
//return std::move(pInt); Will compile but the ownership is lost
return pInt;
}
private:
std::unique_ptr<int> pInt;
};
class Derived2: public Base
{
public:
Derived2() {};
virtual std::unique_ptr<int> get()
{
std::unique_ptr<int> pInt(new int());
return pInt;
}
private:
std::unique_ptr<int> pInt;
};
Derived1 的 get 实现不会隐式转移所有权,因为成员指针变量不是 eXpiring 值,而 Derived2 的实现可以。这种行为在标准中有很好的记录
参见 12.8 §34 和 §35:
当满足某些条件时,允许省略实现 类对象的复制/移动构造 [...] 复制/移动操作,称为复制省略,被允许在 [...] 具有类返回类型的函数中的 return 语句,当 表达式是非易失性自动对象的名称,其 与函数返回类型相同的 cv 非限定类型 [...]
当满足省略复制操作的条件并且 要复制的对象由左值指定,重载决议为 首先执行选择副本的构造函数,就好像 对象由右值指定。
尽管如此,如果我通过std::move 显式转移所有权,则成员指针将来将无法使用。
或者,我必须将指针定义为shared_ptr,但这对于实现Derived2::get 来说是额外的开销。
注意 应该考虑到Derived2::get的出现比Derived1::get更多,所以使用std:: shared_ptr的设计决策会产生相当大的相对影响。
【问题讨论】:
-
你没有说出你想要达到的目标,所以很难提出选择。您是否考虑过 (a) 返回一个原始指针,如果它只是需要被观察; (b) 返回一个弱指针?
-
@ForEveR 然后你会得到一个资源 拥有 同时由 2 个不同的智能指针类。当一个删除它时,另一个会做什么?
-
@RichardCritten 什么都没有。采用
unique_ptr的shared_ptr构造函数获取指向对象的所有权,而unique_ptr释放所有权。如果pInt旨在保留所有权,但不是出于您提供的原因,这不是一个好主意。 -
让
get()返回一个unique_ptr的引用怎么样?
标签: c++ pointers c++11 shared-ptr unique-ptr