C++11 强制仅移动语义

C++11 强制仅移动语义,c++11,move-semantics,class-design,deleted-functions,C++11,Move Semantics,Class Design,Deleted Functions,我对C++11比较陌生,尽管我使用以前的版本已经很多年了。 这是强制一个物体只能移动的正确方法吗 class CResource { public: CResource(); CResource(CResource &&); CResource & operator=(CResource &&); private: CResource(const CResource &) = delete; CResou

我对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和下划线的评论进行编辑

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);
#包括
#定义STR_名称
#定义静态断言NOCOPYASSIGN(clazz)\
static_assert(!std::is_copy_assignable::value\
STR_NAME(clazz)“是可分配的副本”;
#定义静态断言NOCOPYCONSTRUCT(clazz)\
静态断言(!std::is\u copy\u constructible::value\
STR_NAME(clazz)“是可复制的”;
#定义静态\断言\移动分配(clazz)\
静态断言(std::is_UMove\u assignable::value\
STR_NAME(clazz)“!是移动的还是可分配的”);
#定义静态断言移动构造(clazz)\
静态断言(std::is\u move\u constructible::value\
STR_NAME(clazz)“!可以移动吗?”;
#定义静态断言引用类(clazz)\
静态断言移动赋值(clazz)\
静态断言移动构造(clazz)\
静态断言不可复制符号(clazz)\
静态断言不可复制构造(clazz)
静态断言引用类(CResource);

这些将通过Visual Studio 2017。

您的方法仅强制移动

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


但是,请注意,
收单机构资源
代码返回对局部变量的引用,因此具有未定义的行为。您应该按值返回。

您的方法仅强制移动

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


但是,请注意,
收单机构资源
代码返回对局部变量的引用,因此具有未定义的行为。您应该按值返回。

afaics:没有必要将
删除的内容也
私有的
;这只会给用户带来另一个多余的错误。看见从语义上考虑,您希望公众知道他们不能使用已删除的方法。谢谢,这是对我在=delete不存在时编写的代码的一次回击。我会改变的。我更关心的是我是否只强制搬家?afaics:没有必要把
删除的东西也
私有的
;这只会给用户带来另一个多余的错误。看见从语义上考虑,您希望公众知道他们不能使用已删除的方法。谢谢,这是对我在=delete不存在时编写的代码的一次回击。我会改变的。我更关心的是我是否只是强制搬家?