我是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。
答案 0 :(得分:3)
您的方法强制执行仅限移动。
然而,仅仅存在一个移动构造函数/赋值运算符已经抑制了复制构造函数和赋值运算符的生成;不需要明确删除。在C ++ 11早期的草案中,只有少数编译器没有正确实现这一部分。
但请注意,您的AcquireResource
代码返回对局部变量的引用,因此具有未定义的行为。你应该按价值回归。