Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

my class has no suitable copy constructor – depending if the argument of the constructor is const or not

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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;
}

>Solution :

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

  • use a copy constructor which takes a const reference
  • add a move constructor
  • use C++17 (either by using a newer compiler version or by passing the --std=c++17 command line option to your compiler

Edit:
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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading