Question:
I am learning c++, and i created a class to represent complex numbers. I created a copy constructor with the format
complex(const complex &c);
and the program worked fine.
Then, i removed the const (so it became: complex( complex &c);
) and the program doesn't work. It gives me this error:
"message": "class \"complex\" has no suitable copy constructor"
and it refers to the add method. The add method is this:
complex complex::add(complex &c){
return complex( re + c.re, im + c.im);
};
If i do not add this method (and methods that generally return a complex number that is created in the return line, like this: return complex (integer_variable_Re, integer_variable_Im)
) the program works fine. When i add these kinds of methods, it throws me the error. I cannot understand why this doesn't work, as it should call the constructor that takes two integers and not the copy constructor.
Specs: Ubuntu: 20.04Lts
IDE: VScode
Compliler: G++ 9.4
(it says somewhere this: 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
, do not know if it it the compliler standard.)
Whole error message:
[{ "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 }]
Whole program:
#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;
}
Before C++17, the following line
return complex( re + c.re, im + c.im);
actually includes two object creations. First an unnamed temporary object is constructed using two double
parameters. Then a copy of this object is made to where the return value is stored. This second copy is the reason for your compiler error. A copy constructor can only be used to copy a temporary object, if it is declared like this:
complex(const complex&);
If you omit the const
qualifier, you cannot pass a temporary object.
With the introduction of mandatory copy elision in C++17, there is no copy (or move) involved in the line mentioned above. Thus your program compiles fine. Your compiler, which is rather old, does not use C++17 by default and so refuses to compile the program.
To solve your problem, you could either
const
reference--std=c++17
command line option to your compilerEdit:
You should also fix the problem that @Jason Liam mentions in this answer. As mentioned there, your program is ill-formed and should not compile even with the const
constructor.