提问人:MIKE PAPADAKIS 提问时间:10/21/2022 最后编辑:MIKE PAPADAKIS 更新时间:10/21/2022 访问量:483
我的类没有合适的复制构造函数 - 取决于构造函数的参数是否为 const
my class has no suitable copy constructor - depending if the argument of the constructor is const or not
问:
问题:
我正在学习 c++,我创建了一个类来表示复数。我创建了一个复制构造函数,其格式为
complex(const complex &c);
而且程序运行良好。
然后,我删除了常量(所以它变成了:),程序不起作用。它给了我这个错误:complex( complex &c);
"message": "class \"complex\" has no suitable copy constructor"
它指的是 Add 方法。add 方法是这样的:
complex complex::add(complex &c){
return complex( re + c.re, im + c.im);
};
如果我不添加此方法(以及通常返回在返回行中创建的复数的方法,如下所示:),则程序工作正常。当我添加这些方法时,它会给我带来错误。我不明白为什么这不起作用,因为它应该调用需要两个整数的构造函数而不是复制构造函数。return complex (integer_variable_Re, integer_variable_Im)
规格:Ubuntu的:20.04Lts
IDE:VScode
编译器:G++ 9.4
(它在某处说:,不知道它是否是编译者标准。GNU C17 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu) compiled by GNU C version 9.4.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
整个错误消息:
[{ "resource": "/home/papaveneti/Documents/Programming/LearnCpp/complex_classStack.cpp", "owner": "C/C++", "code": "334", "severity": 8, "message": "class \"complex\" has no suitable copy constructor", "source": "C/C++", "startLineNumber": 48, "startColumn": 12, "endLineNumber": 48, "endColumn": 19 }]
整个程序:
#include <iostream>
#include <math.h>
using namespace std;
class complex {
public:
complex (double r, double i); // constructor
// only method that does not specify type
//default constructor
complex ();
//copy cosntructor
complex( complex &c);
// methods:
complex add(complex &c);
void norm1();
private:
// fields:
double re, im;
double norm;
};
//constructor does not need to name a type
complex::complex(double r=0.0, double i=0.0){ // default values are 0
re = r; im = i;
norm1();
};
complex::complex(){
re=im=0;
}
complex::complex( complex &c){
re=c.re;
im=c.im;
}
void complex::norm1(){
norm = sqrt(re*re + im*im);
};
complex complex::add(complex &c){
return complex( re + c.re, im + c.im);
};
int main(){
complex c1(3,4), c2(1,2);
return 0;
}
答:
在 C++ 17 之前,以下行
return complex( re + c.re, im + c.im);
实际上包括两个对象创建。首先,使用两个参数构造一个未命名的临时对象。然后,将此对象的副本复制到存储返回值的位置。第二个副本是编译器错误的原因。复制构造函数只能用于复制临时对象,如果它是这样声明的:double
complex(const complex&);
如果省略限定符,则无法传递临时对象。const
随着 C++ 17 中强制复制省略的引入,上述行中不涉及复制(或移动)。因此,您的程序可以正常编译。您的编译器相当旧,默认情况下不使用 C++17,因此拒绝编译程序。
要解决您的问题,您可以
- 使用采用引用的复制构造函数
const
- 添加 Move 构造函数
- 使用 C++17(通过使用较新的编译器版本或将命令行选项传递给编译器
--std=c++17
编辑:
您还应该解决@Jason Liam在此答案中提到的问题。如上所述,您的程序格式不正确,即使使用构造函数也不应编译。const
评论
该程序在所有 C++ 版本中格式不正确,gcc 和 msvc 在接受代码时是错误的,因为在类外部定义构造函数时,您为两个参数提供了默认参数,从而将其转换为默认构造函数。这是不允许的,叮当拒绝了它。complex::complex(double r, double)
从默认参数文档:
对于非模板类的成员函数,类外定义允许使用默认参数,并与类主体内的声明提供的默认参数组合在一起。如果这些类外默认值将成员函数转换为默认构造函数或复制/移动(自 C++ 11 起)构造函数/赋值运算符,则程序格式不正确
(强调我的)
要解决这个问题,您必须确保在类外部实现 ctor 时不要添加这些默认参数,以避免将其转换为默认 ctor。此外,如果您使用的是 C++11 或 C++14,则必须向复制 ctor 的参数添加低级常量,因为在 C++17 之前没有强制复制省略。
这是 gcc 错误:
这是 msvc 错误:
评论
complex::complex(double r=0, double i=0)
complex::complex()
评论
double