自动生成的移动操作和原始指针成员

时间:2014-03-10 17:33:22

标签: c++ pointers c++11 move

考虑一个MemoryMappedFile类,其中包含以下数据:

class MemoryMappedFile
{
....
private:
    // RAII wrapper to some OS-specific raw handle (e.g. Win32 HANDLE),
    // representing the memory-mapped file.
    Handle m_handle;

    // Pointer to file begin (first file byte).
    BYTE* m_first;

    // Pointer to file end (one byte past last file byte).
    BYTE* m_last;
};

Handle类是某些特定操作系统原始C类句柄的一些RAII包装器(例如,想到Win32 HANDLE)。它不可复制,但它是可移动的 相反,m_firstm_last是与文件内容映射的内存区域内的原始指针。

我希望MemoryMappedFile可移动(但不能复制,就像Handle类一样。)

如果它不是原始指针,根据C ++ 11的自动生成移动构造函数的规则通过成员移动,该类将自动可移动。

不幸的是,原始指针迫使我编写自定义移动构造函数:

MemoryMappedFile::MemoryMappedFile(MemoryMappedFile&& other)
    : m_handle( std::move(other.m_handle) )
{
    // Move m_first
    m_first = other.m_first;
    other.m_first = nullptr;

    // Move m_last
    m_last = other.m_last;
    other.m_last = nullptr;
}

如果C ++标准库有某种形式的“dumb-as-against-to-smart-movable”指针,零开销,就像原始指针一样好(这很好,因为观察非拥有指针),但定义了移动操作(移动构造函数和移动赋值),这样编译器就可以在将这些指针作为数据成员的类中自动生成正确的移动操作。

在C ++标准库中还是在Boost中有这样的东西?

还是有其他方法可以实现相同的目标(除了编写我自己的自定义ObservingPointer类,包装原始指针和定义移动操作)?

2 个答案:

答案 0 :(得分:4)

只需将std::unique_ptr与您自己的noop_deleter一起使用。

答案 1 :(得分:2)

我经常需要一个既可复制又可移动的“智能”指针,但是有一个明确定义的移动状态,所以我写了tidy_ptr这是一个“哑”的智能指针,没有什么特别的,除了移动时归零。该类型是可复制的,因此要获得您想要的类的语义,您仍然需要将复制操作定义为已删除(或者只使用带有no-op删除器的std::unique_ptr)。

我试图说服标准委员会observer_ptr, "the world's dumbest smart pointer",应该有这种行为,但大家一致认为它应该像内置指针一样(除了构造函数中的零初始化)。我仍然认为它应该归零。该文件显示non_owning_ptr,它是unique_ptr的别名,带有无操作删除器,可以执行您想要的操作。