(避免使用)C++中的复制机制

dua*_*ane 8 c++

可能重复:
为什么不允许复制构造函数和赋值运算符?

我正在从一个坚实的C背景学习C++,并且急于避免我从reddit和黑客新闻中收集到的以前C++的错误,我一直在使用Google C++样式指南和LLVM的源代码作为我自己的参考码.突出的一点是项目使用以下代码.以下内容取自LLVM的include/Support/MemoryBuffer.h:

MemoryBuffer(const MemoryBuffer &); // DO NOT IMPLEMENT
MemoryBuffer &operator=(const MemoryBuffer &); // DO NOT IMPLEMENT
Run Code Online (Sandbox Code Playgroud)

谷歌回应了这种用法.显然,禁用这些"复制构造函数"是一件好事.

所以我的问题是:为什么这些东西如此可怕,并且(如果它们没有防范)它们的用途是什么样的,它在代码中会产生什么影响?

Eti*_*tel 9

当对象必须管理自己的资源(例如内存或系统句柄)时,默认的复制构造函数和赋值运算符不再适用.这意味着你必须覆盖它们.

但是,有时复制这样的对象没有任何意义.或者,换句话说,某些对象不是要复制的.有时甚至不可能编写这样的构造函数或赋值运算符.在这种情况下,最好禁用复制和分配,以确保它们不会被意外复制.

标准iostream是一个很好的例子.

总而言之,这是一个特殊情况.绝对不是你经常会遇到的事情.

  • @GWW:或锁,或某些类型的智能指针.另外,在C++ 03中很难避免*某种类型的复制语义(如何从函数中返回对象?).如果您愿意,在C++ 11中移动语义可以让您完全远离复制对象. (3认同)

Moo*_*ice 6

什么好怕拷贝构造函数和他们不应该被看作是这样的.

然而,也就是说,有时复制对象根本没有意义.在您提供的示例中,内存缓冲区是一个很好的复制示例.它可能已用于存储已分配对象的数据.副本提供什么?所有这些对象的原始数据的副本,而不是其他内容(例如,对象不能使用它来取消分配).

因此,一旦我们确定复制我们的类是没有意义的,那么我们应该阻止程序员这样做也是有意义的.如果我们不自己声明它们,编译器将偷偷摸摸并为我们制作默认的复制构造函数和赋值运算符.因此,如果我们声明它们(我们不需要提供实现)并确保这些声明是私有的,那么如果程序员试图这样做,编译器将发出编译错误.