什么是在C++ 03中模拟=删除以限制复制/赋值操作的最简单方法?

Phi*_*uil 3 c++ copy-constructor c++03 c++98

C++ 11通过允许您使用"= delete"语法将隐式编译器定义的方法标记为verboten来解决长期困扰我的问题. 维基百科了解更多信息.

class Foo
{
public:
     Foo();
    ~Foo();

    // No copy
    Foo(Foo const &) = delete;
    Foo& operator=(Foo const &) = delete;
};
Run Code Online (Sandbox Code Playgroud)

我不希望复制或分配的类的复制和赋值运算符总是很难搞乱.这是一个很大的锅炉板代码,使它们成为私有的,然后通常会有成员数据,没有一个默认的构造函数,需要一些挥手让编译器对你想要没有人调用的函数感到高兴.

class Bar
{
public:
   explicit Bar(UniqueResourceID id): m_data(id) { }
   ~Bar();

protected:
   SomeHandle  m_data; // no default constructor

// all this crap to keep from being able to copy.  Do not use any of these!!
private:
   Bar() { } // ERROR: m_data has no default constructor
   static UniqueResourceID s_invalidID; // now I'm making the problem worse,
                                        // because I don't actually need this
                                        // for anything real, except to shut
                                        // up some errors.
   Bar(Bar const &o): m_data(s_invalidID) { }
   Bar& operator =(Bar const &o): { return *this; }
};
Run Code Online (Sandbox Code Playgroud)

不幸的是,我必须使用的一些编译器不是C++ 11编译器,也不提供= delete.处理这些问题的最佳方法是什么?(请告诉我有比第二个代码片段更好的方法.)

Sor*_*ren 6

你正在编写所有额外的废话,因为你实际上是在定义deleted运算符的主体- 我认为你不必这样做,而我所做的只是在没有任何实现的情况下进行声明,就像这样;

class Bar
{
public:
   explicit Bar(UniqueResourceID id): m_data(id) { }
   ~Bar();

protected:
   SomeHandle  m_data; // no default constructor

private:
   Bar(); 
   Bar(Bar const &o);
   Bar& operator =(Bar const &o);
};
Run Code Online (Sandbox Code Playgroud)

这并不比编写= delete附加到它的方法更冗长.

编辑:你的定义

....
private:
   Bar() {}
Run Code Online (Sandbox Code Playgroud)

实际上是危险的,因为它允许从内部的其他方法调用操作符Bar而不会产生任何错误(链接器或编译器)

  • 应该提到的是,虽然这完全是正确的答案,但是当你试图调用它们时(特别是在类范围内)你得到的错误是不同的.尝试使用外部/受保护设置会出现访问错误,在类范围内,您将获得未定义的符号错误. (2认同)