复制构造函数的签名而不引用

Fer*_*jka 2 c++ constructor copy-constructor c++11

如果我有一个Point类,复制构造函数应如下所示:

Point(const Point &p);
Point(Point &p);
Run Code Online (Sandbox Code Playgroud)

但是,如果我想创建一个需要Point的构造函数呢?为什么它被视为复制构造函数而不是构造函数?

Point(const Point p)
Run Code Online (Sandbox Code Playgroud)

编译错误:"类"的复制构造函数"Point"可能没有"Point"类型的参数

Ser*_*eyA 10

您不能使用复制构造函数签名来按值接受参数.原因很简单 - 为了按值传递参数,您需要调用复制构造函数,这将需要按值传递参数,并将调用复制构造函数...欢迎使用无限递归.

编译器通过不允许这个构造来节省很多麻烦.


Chr*_*ckl 5

\n
Point(const Point p)\n
Run Code Online (Sandbox Code Playgroud)\n\n

为什么它被视为复制构造函数而不是构造函数?

\n
\n\n

它不是。

\n\n

正如 \xc2\xa712.8/2 中的标准所述:

\n\n
\n

如果类的非模板构造函数X的第一个参数的类型为X&、或,并且没有其他参数,或者所有其他参数都有默认参数 (...),则该类的非模板构造函数是复制构造函数const X&volatile X&const volatile X&

\n
\n\n

事实上,你的声明格式不正确。\xc2\xa712.8/6 说:

\n\n
\n

如果类的X第一个参数是类型(可以选择 cv 限定)X并且没有其他参数或者所有其他参数都有默认参数,则类的构造函数的声明是格式错误的。

\n
\n\n

你确实有这样的情况:一个类的构造函数,Point其第一个参数是类型const Point并且没有其他参数。

\n\n

这当然是正式的解释。正如其他人所解释的,这种构造函数的实际含义将是无限递归。

\n\n

也许您担心收到的错误消息。但是,对于编译器生成的诊断消息的内容绝对没有任何规则。这是一个实施质量问题;如果您的编译器认为类“Point”的复制构造函数可能没有“Point”类型的参数是将问题传达给用户的好方法,那么就这样吧。

\n