Copy constructor is not working


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     #include <iostream>
     
    using namespace std;
     
    class cmplex
    {
    int a,b;
    public:
    cmplex(int x,int y){a=x;b=y;cout<<"its inside constructor 1"<<a<<" "<<b<<endl;}
    cmplex(int y){a=y;cout<<"its inside constructor 2 "<<a<<endl;}
    cmplex(){cout<<"its inside constructor 3"<<endl;}
    cmplex(cmplex &c){a=c.a;b=c.b;cout<<"its inside copy constructor 1"<<endl;cout<<a<<b<<endl;}
    };
    int main()
    {
        cmplex c1(2,3),c2(2,33);
        c1=cmplex(2,3),c2=cmplex(2,33);
        cmplex c3=cmplex();//"cmplex c3"
        cmplex c4(c2);
        return 0;
    }
     

I am getting these following errors
prog.cpp: In function ‘int main()’:
prog.cpp:18:15: error: invalid initialization of non-const reference of type ‘cmplex&’ from an rvalue of type ‘cmplex’
cmplex c3=cmplex();
^~~~~~~~
prog.cpp:12:1: note: initializing argument 1 of ‘cmplex::cmplex(cmplex&)’
cmplex(cmplex &c){a=c.a;b=c.b;cout<<"its inside copy constructor 1"<<endl;cout<<a<<b<<endl;}
^~~~~~

Why is this happening?What should I do to solve this problem?
Last edited on
The copy constructor needs to take a const reference as argument, otherwise you will not be able to pass temporary objects.

 
cmplex(const cmplex &c) ...
Remove your copy constructor and it will work.
https://cpppatterns.com/patterns/rule-of-zero.html
Why does this work .I have not mentioned const here
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

class cmplex
{
int a,b;
public:
cmplex(int x,int y){a=x;b=y;cout<<"its inside constructor 1"<<a<<" "<<b<<endl;}
cmplex(int y){a=y;cout<<"its inside constructor 2 "<<a<<endl;}
cmplex(){cout<<"its inside constructor 3"<<endl;}
cmplex(cmplex &c){a=c.a;b=c.b;cout<<"its inside copy constructor 1"<<endl;cout<<a<<b<<endl;}
};
int main()
{
    cmplex c1(2,3),c2(2,33);
    c1=cmplex(2,3),c2=cmplex(2,33);
    cmplex c3;//this line is changed from previous one
    cmplex c4(c2);
    return 0;
}
Last edited on
Because c2 is not a temporary object.

When a function takes a non-const references as argument it implies that the function wants to modify the argument, but modifying a temporary object is usually pointless because it will get destroyed as soon as the function returns so no one gets to see the changes that was made. Since it's usually a mistakes to pass temporary objects to functions that modifies the object it has been made an error.

1
2
3
4
cmplex c3 = cmplex(); // complex() creates a temporary object that will get
                      // destroyed when this line is finished executing. If
                      // the copy constructor modified the temporary object
                      // we wouldn't notice. 
Last edited on
"Why don't I get an error when I don't try to do the thing that invokes the error?"

Isn't that obvious?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

using std::cout;

class cmplex
{
  int a,b;
public:
  cmplex(int x,int y) : a(x), b(y) {cout<<"ctor A "<<a<<' '<<b<<'\n';}
  cmplex(int y) : a(y), b(42) {cout<<"ctor B "<<a<<' '<<b<<'\n';}
  cmplex() : a(7), b(13) {cout<<"ctor C "<<a<<' '<<b<<'\n';}
  cmplex(cmplex &c) : a(c.a), b(c.b) {cout<<"copy ctor "<<a<<' '<<b<<'\n';}
  cmplex& operator=(const cmplex &c)
    { a=c.a; b=c.b; cout<<"assign "<<a<<' '<<b<<'\n'; return *this;}

};
int main()
{
    cmplex c1(1,2);
    cmplex c2(3);
    c1 = cmplex(4,5);
    c2 = cmplex(6,7);
    cmplex c3;
    cmplex c4( c2 );
    c2 = c3 = c1;
    //cmplex c5( cmplex(8) ); // cannot convert cmplex into cmplex&
    return 0;
}

ctor A 1 2
ctor B 3 42
ctor A 4 5
assign 4 5
ctor A 6 7
assign 6 7
ctor C 7 13
copy ctor 6 7
assign 4 5
assign 4 5


The cmplex(8) on line 26 is an unnamed temporary object. It does not exist after the statement.
The call to copy constructor wants to create a reference to its argument object.
If you create a reference to temporary, the reference could outlive the referred object.

Lets assume that you put $1000 to your pocket. You remember that you did so. Later, you would like to use some of that money. Alas, it was not "real" $1000, but a time-limited offer. The offer has already expired. You have a problem.

You can create a const reference (like the assignment operator does). That extends the lifetime of the temporary.
Thanks
Topic archived. No new replies allowed.