我如何允许移动构造并不允许分配和复制班级的构造 [英] How do I allow move construction and disallow assignment and copy construction of a class

查看:50
本文介绍了我如何允许移动构造并不允许分配和复制班级的构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以允许move构造函数并禁止复制构造和赋值.我可以想到几个带有文件指针和缓冲区指针(资源句柄)的类,这些类将从复制构造和分配中受益.

Is there a way to allow a move constructor and disallow copy construction and assignment. I can think of several classes with file pointers and buffer pointers (resource handles etc) that would benefit from being copy constructed and assigned.

我正在使用VC2010&GCC 4.5.2.我知道我将不得不在VC2010类头中声明空的私有分配和复制构造函数,据我所知,GCC允许在方法执行相同操作后进行某种删除签名.

I am using VC2010 & GCC 4.5.2. I know that I would have to declare empty private assignment and copy constructors in the VC2010 class headers and as far as I am aware GCC allows some sort of delete signature after the method to do the same thing.

如果任何人都拥有像这样的骨架类的一个很好的例子,那么我将不胜感激.提前致谢约翰

If anyone has a good example of a skeleton class like this and the advantages I would be very grateful. Thanks in advance John

这是我想允许其举动但我也想防止直接分配的一类示例.只是使复制构造函数和operator = private成为问题吗?

Here is an example of a class for which I would like to allow moves but I would also like to prevent direct asssignment. Is it simily a matter of making the copy constructor and operator=private?

class LoadLumScanner_v8002 : public ILoadLumScanner { 
public:
// default constructor
LoadLumScanner_v8002();

// copy constructor
LoadLumScanner_v8002(const LoadLumScanner_v8002& rhs);

// move constructor
LoadLumScanner_v8002(LoadLumScanner_v8002&& rhs);

// non-throwing copy-and-swap idiom unified assignment
inline LoadLumScanner_v8002& operator=(LoadLumScanner_v8002 rhs) {
    rhs.swap(*this);
    return *this;
}

// non-throwing-swap idiom
inline void swap(LoadLumScanner_v8002& rhs) throw() {
    // enable ADL (not necessary in our case, but good practice)
    using std::swap;
    // swap base members
    // ... 
    // swap members
    swap(mValidatedOk, rhs.mValidatedOk);
    swap(mFile, rhs.mFile);
    swap(mPartNo, rhs.mPartNo);
    swap(mMediaSequenceNo, rhs.mMediaSequenceNo);
    swap(mMaxMediaSequenceNo, rhs.mMaxMediaSequenceNo);
    swap(mLoadListOffset, rhs.mLoadListOffset);
    swap(mFirstLoadOffset, rhs.mFirstLoadOffset);
    swap(mLoadCount, rhs.mLoadCount);
    swap(mLoadIndex, rhs.mLoadIndex);
    swap(mLoadMediaSequenceNo, rhs.mLoadMediaSequenceNo);
    swap(mLoadPartNo, rhs.mLoadPartNo);
    swap(mLoadFilePath, rhs.mLoadFilePath);
}

// destructor
virtual ~LoadLumScanner_v8002();
}

推荐答案

您提到的两个解决方案都可以正常工作.

Both of the two solutions you mention work fine.

1.

class MoveOnly
{
   MoveOnly(const MoveOnly&);
   MoveOnly& operator=(const MoveOnly&);
public:
   MoveOnly(MoveOnly&&);
   MoveOnly& operator=(MoveOnly&&);
};

2.

class MoveOnly
{
public:
   MoveOnly(const MoveOnly&) = delete;
   MoveOnly& operator=(const MoveOnly&) = delete;
   MoveOnly(MoveOnly&&);
   MoveOnly& operator=(MoveOnly&&);
};

"= delete"签名是C ++ 11的新增功能(与右值引用一样),其含义基本上与C ++ 03技术相同(声明私有且未定义).C ++ 11解决方案的优势在于,它肯定会在编译时捕获错误,而不会延迟到链接时间.

The "= delete" signature is new with C++11 (as is the rvalue reference), and means essentially the same thing as the C++03 technique (declare private and don't define). The advantage of the C++11 solution is that it will for sure catch mistakes at compile time, not delay until link time.

您的编译器可能尚未支持"= delete",在这种情况下,您将不得不依靠第一个解决方案.

Your compiler may not yet support "= delete" and in that case, you'll have to fall back on the first solution.

第三个解决方案是默认复制成员:

A third solution is to default the copy members:

class MoveOnly
{
public:
   MoveOnly(MoveOnly&&);
   MoveOnly& operator=(MoveOnly&&);
};

声明移动特殊成员时,无论是否默认,否则编译器将隐式添加已删除的副本成员,如果您不另外声明它们的话.您的编译器可能尚未实现此功能.

When a move special member is declared, whether defaulted or not, then the compiler will implicitly add deleted copy members if you do not declare them otherwise. Your compiler may or may not implement this feature yet.

这篇关于我如何允许移动构造并不允许分配和复制班级的构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆