How do I allow move construction and disallow assignment and copy construction of a class

怎甘沉沦 提交于 2021-01-27 04:42:11

问题


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.

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

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();
}

回答1:


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&&);
};

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.

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.



来源:https://stackoverflow.com/questions/10472718/how-do-i-allow-move-construction-and-disallow-assignment-and-copy-construction-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!