3

当我想在 C++ 中禁止类复制时,我通常声明一个私有 operator=和一个复制构造函数,但我不实现它们:

class MyClass
{
  char* _str;
  int _len;
  MyClass(const MyClass& rhs);            //No implementation
  MyClass& operator=(const MyClass& rhs); //No implementation
public:
  MyClass();
  MyClass(const char *);
}

这被认为是一种不好的风格吗?还有另一种方法可以做到这一点吗?

4

3 回答 3

10

在 C++11 中,您可以显式删除这些函数(这比省略实现更可取,因为它更具可读性,并且总是会生成编译器错误,而不仅仅是链接器错误):

class MyClass
{
  char* _str;
  int _len;
  MyClass(const MyClass& rhs) = delete;
  MyClass& operator=(const MyClass& rhs) = delete;
public:
  MyClass();
  MyClass(const char *);
}

在 C++03 中,您可以使用诸如此类的基类boost::noncopyable来实现相同的效果。这可能更具可读性(这与您的方法基本相同 - 此基类具有私有复制构造函数和赋值运算符,因此从它继承将使您的类不可复制):

class MyClass : boost::noncopyable
{
  char* _str;
  int _len;
public:
  MyClass();
  MyClass(const char *);
}

C++ 中浅拷贝和深拷贝之间的区别完全在于你如何实现你的拷贝构造函数(因为你的赋值运算符应该使用你的拷贝构造函数来实现)。如果你没有,那么浅拷贝和深拷贝都不可能,如果你有,这取决于它是如何实现的。

于 2012-11-19T15:11:08.170 回答
3

您可以创建一个预处理器宏来实现相同的目的,例如

#define DISABLE_COPY_AND_ASSIGN(className) private: \
    className(const className&); \
    className& operator=(const className&);

然后像这样使用它:

class MyClass
{
   DISABLE_COPY_AND_ASSIGN(MyClass)
public:
   ....
};

您也可以从中得出boost::noncopyable

class MyClass : boost::noncopyable
{
public:
   ....
};

此外,在 C++11 中,您可以使用= delete

MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
于 2012-11-19T15:13:46.783 回答
2

有两种方法,两者都会导致编译错误:

C++11 方式:

class MyClass
{
  char* _str;
  int _len;
  MyClass(const MyClass& rhs) = delete;
  MyClass& operator=(const MyClass& rhs); = delete
public:
  MyClass();
  MyClass(const char *);
};

C++03方式:

class MyClass
{
  char* _str;
  int _len;
public:
  MyClass();
  MyClass(const char *);

  MyClass(const MyClass& rhs);            //No implementation
  MyClass& operator=(const MyClass& rhs); //No implementation
}

如果你只是将复制构造函数声明为 public,你会得到链接器错误,但编译会通过。由于编译发生在链接之前,最好中断编译,因为您会更快地发现错误。

于 2012-11-19T15:15:19.323 回答