执行仅移动语义

时间:2018-04-13 10:04:56

标签: c++11 move-semantics class-design deleted-functions

我是C ++ 11的新手,虽然我已经使用过多年的早期版本了。 这是强制对象只能移动的正确方法吗?

class CResource
{
public:
    CResource();

    CResource(CResource &&);
    CResource & operator=(CResource &&);

private:
    CResource(const CResource &) = delete;
    CResource & operator=(const CResource &) = delete;

    void * m_pResource;
};

class CAcquireResource
{
public:
    CResource && AcquireResource();
};

CResource && CAcquireResource::AcquireResource()
{
    CResource res;
    return std::move(res);
}

在Sebastian Redl和underscore_d

的评论后编辑
class CResource
{
public:
    CResource();
    CResource(CResource &&);
    CResource & operator=(CResource &&);
};

class CAcquireResource
{
public:
    CResource AcquireResource();
};

CResource CAcquireResource::AcquireResource()
{
    CResource res;
    return std::move(res);
}

断言也在坚持......

#include <type_traits>
#define STR_NAME(s) #s
#define STATIC_ASSERT_NOCOPYASSIGN(clazz)                                   \
    static_assert(!std::is_copy_assignable<clazz>::value,                   \
        STR_NAME(clazz) " is_copy_assignable");

#define STATIC_ASSERT_NOCOPYCONSTRUCT(clazz)                                \
    static_assert(!std::is_copy_constructible<clazz>::value,                \
        STR_NAME(clazz) " is_copy_constructible");

#define STATIC_ASSERT_MOVEASSIGN(clazz)                                     \
    static_assert(std::is_move_assignable<clazz>::value,                    \
        STR_NAME(clazz) " !is_move_assignable");

#define STATIC_ASSERT_MOVECONSTRUCT(clazz)                                  \
    static_assert(std::is_move_constructible<clazz>::value,                 \
        STR_NAME(clazz) " !is_move_constructible");

#define STATIC_ASSERT_REFERENCECLASS(clazz)                                 \
    STATIC_ASSERT_MOVEASSIGN(clazz)                                         \
    STATIC_ASSERT_MOVECONSTRUCT(clazz)                                      \
    STATIC_ASSERT_NOCOPYASSIGN(clazz)                                       \
    STATIC_ASSERT_NOCOPYCONSTRUCT(clazz)    

STATIC_ASSERT_REFERENCECLASS(CResource);

这些通过Visual Studio 2017。

1 个答案:

答案 0 :(得分:3)

您的方法强制执行仅限移动。

然而,仅仅存在一个移动构造函数/赋值运算符已经抑制了复制构造函数和赋值运算符的生成;不需要明确删除。在C ++ 11早期的草案中,只有少数编译器没有正确实现这一部分。

但请注意,您的AcquireResource代码返回对局部变量的引用,因此具有未定义的行为。你应该按价值回归。