为什么人们要定义一个私有的拷贝构造函数?
什么时候让复制构造函数和赋值操作符私有是一个好的设计?
如果类中没有指向唯一对象(如文件名)的指针或句柄的成员,那么在哪些情况下私有拷贝构造函数是个好主意呢?
同样的问题也适用于赋值运算符。考虑到大多数C++都围绕着复制对象和通过引用传递,有没有涉及私有复制构造函数的好设计?
发布于 2011-07-25 09:57:38
一些对象表示不能或不应该被复制的特定实体。例如,您可以防止复制表示应用程序使用的日志文件的对象,这与代码的所有部分都使用单个日志文件的期望相对应。使用意外或不适当复制的对象可能会导致在日志中出现无序内容、当前日志大小的不准确记录、多次尝试(某些失败)以“滚动”到新的日志文件名或重命名现有的日志文件名。
另一个用途是通过虚拟函数强制复制。由于构造函数不能为virtual,因此一种常见的做法是防止直接访问复制构造函数,并提供一个virtual Base* clone()方法来返回指针所指向的实际运行时类型的副本。这可以防止Base b(derived)出现意外切片。
另一个例子:一个非常简单的智能指针对象,它简单地删除了在构造函数中给定的指针:如果它不支持引用计数或其他处理多个所有者的方式,并且不想有意外的std::auto_ptr风格的所有权转移的风险,那么简单地隐藏复制构造函数就可以提供一个很好的小智能指针,在有限的可用情况下它是快速和有效的。如果在编译时出现试图复制它的错误,就会有效地询问程序员“嘿--如果你真的想这么做,就把我改成一个共享指针,否则就退后!”。
发布于 2011-07-25 09:39:23
一个用例是单例模式,其中只能有一个类的实例。在这种情况下,您需要将构造函数和赋值operator=设置为私有,这样就无法创建多个对象。创建对象的唯一方法是通过GetInstance()函数,如下所示。
// An example of singleton pattern
class CMySingleton
{
public:
static CMySingleton& GetInstance()
{
static CMySingleton singleton;
return singleton;
}
// Other non-static member functions
private:
CMySingleton() {} // Private constructor
~CMySingleton() {}
CMySingleton(const CMySingleton&); // Prevent copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent assignment
};
int main(int argc, char* argv[])
{
// create a single instance of the class
CMySingleton &object = CMySingleton::GetInstance();
// compile fail due to private constructor
CMySingleton object1;
// compile fail due to private copy constructor
CMySingleton object2(object);
// compile fail due to private assignment operator
object1 = object;
// ..
return 0;
}发布于 2011-07-25 09:47:24
一个非常糟糕的例子:
class Vehicle : { int wheels; Vehicle(int w) : wheels(w) {} }
class Car : public Vehicle { Engine * engine; public Car(Engine * e) : Vehicle(4), engine(e) }
...
Car c(new Engine());
Car c2(c); // Now both cars share the same engine!
Vehicle v;
v = c; // This doesn't even make any sense; all you have is a Vehicle with 4 wheels but no engine.“复制”汽车是什么意思?(汽车是汽车模型,还是汽车的实例?复制它是否会保留车辆登记?)
将一辆车分配给另一辆车意味着什么?
如果操作没有意义(或者仅仅是未实现),则标准做法是将复制构造函数和赋值操作符设置为私有,如果使用它们而不是奇怪的行为,则会导致编译错误。
https://stackoverflow.com/questions/6811037
复制相似问题