【发布时间】:2016-11-28 19:02:43
【问题描述】:
编辑:使Foo 和Bar 变得不那么琐碎,直接替换为shared_ptr<> 更加困难。
应该将unique_ptr<> 用作实现移动语义的更简单方法吗?
对于像这样的类
class Foo
{
int* m_pInts;
bool usedNew;
// other members ...
public:
Foo(size_t num, bool useNew=true) : usedNew(useNew) {
if (usedNew)
m_pInts = new int[num];
else
m_pInts = static_cast<int*>(calloc(num, sizeof(int)));
}
~Foo() {
if (usedNew)
delete[] m_pInts;
else
free(m_pInts);
}
// no copy, but move
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
Foo(Foo&& other) {
*this = std::move(other);
}
Foo& operator=(Foo&& other) {
m_pInts = other.m_pInts;
other.m_pInts = nullptr;
usedNew = other.usedNew;
return *this;
}
};
随着数据成员的增加,实现移动变得更加繁琐。但是,可移动数据可以放置在单独的struct 中,其实例由unique_ptr<> 管理。这允许=default 用于移动:
class Bar
{
struct Data
{
int* m_pInts;
bool usedNew;
// other members ...
};
std::unique_ptr<Data> m_pData = std::make_unique<Data>();
public:
Bar(size_t num, bool useNew = true) {
m_pData->usedNew = useNew;
if (m_pData->usedNew)
m_pData->usedNew = new int[num];
else
m_pData->m_pInts = static_cast<int*>(calloc(num, sizeof(int)));
}
~Bar() {
if (m_pData->usedNew)
delete[] m_pData->m_pInts;
else
free(m_pData->m_pInts);
}
// no copy, but move
Bar(const Bar&) = delete;
Bar& operator=(const Bar&) = delete;
Bar(Bar&& other) = default;
Bar& operator=(Bar&& other) = default;
};
除了unique_ptr<> 实例的内存总是在堆上,这样的实现还存在什么其他问题?
【问题讨论】:
-
请
std::unique_ptr当且仅当资源的所有权是唯一的时才使用。std::unique_ptr上的移动语义仅用于转移所有权。 github.com/isocpp/CppCoreGuidelines/blob/master/… -
史前的
calloc是什么? -
@Dan,但这一点也不难......
-
@Dan 对不起,我错过了你的文字:你想使用一些移动语义,
std::unique_ptr将仅用于此目的。
标签: c++ c++11 move-semantics unique-ptr