如果我有一个Point类,复制构造函数应如下所示:
Point(const Point &p);
Point(Point &p);
但是,如果我想创建一个需要Point的构造函数呢?为什么它被视为复制构造函数而不是构造函数?
Point(const Point p)
编译器错误:“类”的复制构造函数“Point”可能没有“Point”类型的参数
答案 0 :(得分:10)
您不能拥有复制构造函数签名来按值接受参数。原因很简单 - 为了按值传递参数,您需要调用复制构造函数,这将需要按值传递参数,并将调用复制构造函数...欢迎使用无限递归。
编译器通过不允许这种构造为您节省了很多麻烦。
答案 1 :(得分:3)
Point(const Point p)
为什么它被视为复制构造函数而不是构造函数?
不是。
正如标准在§12.8/ 2中所述:
类
X
的非模板构造函数是一个复制构造函数 第一个参数的类型为X&
,const X&
,volatile X&
或const volatile X&
,并且没有其他参数或其他所有参数 参数有默认参数(...)。
事实上,您的声明格式错误。 §12.8/ 6说:
如果类
X
的构造函数的声明形式不正确 第一个参数是类型(可选择cv-qualified)X
和其中之一 没有其他参数或其他所有参数都有 默认参数。
您确实拥有:类Point
的构造函数,其第一个参数的类型为const Point
且没有其他参数。
这当然是正式的解释。正如其他人所解释的那样,这种构造函数的实际意义将是无限递归。
也许您担心自己收到的错误消息。但是,编译器生成的诊断消息内容绝对没有任何规则。这是一个实施质量问题;如果您的编译器认为类“Point”的复制构造函数可能没有“Point”类型的参数是向用户传达问题的好方法,那就这样吧。