构造函数深入讲解

类似这样的问题千奇百怪。例如:

1.为什么我明明不想复制对象,而编译器却偏偏这么做了呢?
2.如何关闭复制机制?
3.如何防止隐式转换?
4.为何 int 自动转换成了复数?

类的默认复制构造函数和赋值运算符可以复制所有元素。例如:

至此,p2.x==p1.x 并且 p2.y==p1.y。这可能正是你想要的(而且也是为了和 C 兼容所必需的),但是,以下代码:

在此,默认复制构造函数使得 h2.name==h1.name 并且 h2.p==h2.p。这将导致一场灾难:当函数 f() 运行结束时,会调用 h1 和 h2 的析构函数,这就导致 h1.p 和 h2.p 所指向的对象被 delete 了两次。

如何避免这场灾难?最简单的办法是,将复制构造函数和赋值运算符声明为私有成员,从而关闭复制机制:

如果需要复制机制,我们可以定义自己的复制构造函数和赋值运算符,让它们按我们期待的那样工作。

现在回过头来再看看类 Point。对 Point 来说,可以使用默认的复制机制,但它的构造函数有点问题:

为了便于创建对象(如这里的 orig 和 p1),我们为 Point 的构造函数提供了默认参数。然后,有些人会感到惊讶的事情发生了:调用 f() 时,2 会转换成 Point(2,0)。当我们定义一个接受单个参数的构造函数时,同时亦定义了一种类型转换方式。默认情况下,类型转换是隐式进行的。若想把类型转换改成 显式进行,就要将构造函数声明为 explicit: