explicit copy constructor and overload operators

Hi There,
I have checked high and low for an answer, and many articles say it is not good top declare a copy-constructor as explicit. BUt beside these adivces, I could not find an answer for this I noticed on my test class bellow:

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 TestOverload{
public:
    int i;
    TestOverload(int a = 0);
    explicit TestOverload(const TestOverload &T){
        i = T.i;
    }
    TestOverload operator +(const TestOverload &T){
        TestOverload *tSum =  new TestOverload;
        tSum->i = i+T.i;
        return *tSum;
    }
    static TestOverload &func(int a){
        TestOverload *T =  new TestOverload;
        T->i = a;
        return *T;
    }

};


It seems like compiler (GCC) complains about error: no matching function for call to ‘TestOverload::TestOverload(TestOverload&)’
which is the return line for operator+ overloading (return *tSum;).
Althoug, if I make operator+ as referenced (TestOverload &operator +), everything works fine.

Does anyone knows why?

Regards,
André B.
Last edited on
The explicit keyword when applied to a copy constructor means that object of that class can't
be copied when being passed tofunctions or when being returned from function - (this type of copying is called implicit copying).

This means that the your TestOverload objects have to be paased by reference/pointer:
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
29
30
31
32
33
34
35
36
37
38
39
#include<iostream>
#include<cstring>
#include <iomanip>
using namespace std;


class TestOverload
{
public:
    int i;
    TestOverload(int a = 0);

    explicit TestOverload(const TestOverload &T){} //EXPLICIT copy constructor

};

void funcX(TestOverload a) //ERROR to take TestOverload by value (implicit copying)
{

}

TestOverload funcY() //ERROR - function returning TestOverload by value (implicit copying)
{
    TestOverload a;
    return a; //ERROR  implit copying of TestOverload not allowed

}



int main()
{
    TestOverload to;
    funcX(to); ////ERROR  implicit copying of TestOverload not allowed

    TestOverload too = to;////ERROR  implicit copying of TestOverload not allowed

    TestOverload tot(to); //OK - EXPLICIT copying allowed
}
Last edited on
Also note:
1
2
3
4
5
 TestOverload operator +(const TestOverload &T){
        TestOverload *tSum =  new TestOverload; //If you are returning a copy this is going to leak memory, create this on the stack.
        tSum->i = i+T.i;
        return *tSum;
    }


In fact if you allocate the memory, somewhere you need to free it or you are leaking
The copy-constructor is a special method that can be called without really typing its name.

The copy-constructor is called whenever an object is initialized based on another existing object.

Assuming you have:
1
2
3
4
5
6
class TestOverload{
public:
    int i;
    TestOverload(int a = 0);
    TestOverload(const TestOverload &T);
};


And you write this line:
TestOverload t1 = t2; t1 is created based on t2 values. TestOverload(t2) will be called.

Also, if you have:
1
2
3
4
void myFunc(TestOverload t)
{
//code
}

t will be created based on the object you pass when you call myFunc. This means copy-constructing!

Attention:
t1 = t2;
This doesn't call the copy-constructor. t1 is already created in this case, it's already constructed. This line calls the assignment operator function.

--

But if you don't want anyone to make these implicit calls, just put the explicit keyword before the copy constructor. This way, the only way to call the copy-constructor is typing its name. No implicit calls will be made. This also means it won't be possible to pass the object by value to any function, or make initializations like ClassType obj1 = obj2;

There are other special functions that can be implicitly called, like the converting constructor. This one is more common to make explicit.
Topic archived. No new replies allowed.