0

I was puzzled as why I had to write copy constructor of this one class when I defined a function inside another class with the return type of the first mentioned class.

For example:

class Foo{
    // attributes
public:
    Foo(){...}

    // I had to write the CC
    Foo(const Foo& obj){
        //...
    }
}

class Bar{
// ....

// This is the function
Foo SomeFunction()
{
    Foo myVar;

    // ....

    return myVar;
}

I checked by couting that the copy constructor is actually being called.

I need confirmation though because it would seem more logical to me that the default constructor is called in this situation, like in this line where myVar is created.

I'm a beginner so I'm trying to wrap my head around these calls.

developer10
  • 1,450
  • 2
  • 15
  • 31

2 Answers2

3

The line

Foo myFunc;

calls the default constructor.

The line

return myFunc;

calls the copy constructor since the return type of the function is Foo. The object returned from the function is not myFunc but a copy of myFunc. myFunc gets deleted when the function returns. The copy is what the calling function gets.

If the compiler is able to use RVO (return value optimization), then myFunc is returned to the calling function, not a copy. In that case, the copy constructor will not get called.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    actually, depending on the optimization capabilities of the compiler, the return statement may actually call the move constructor as well if NRVO is applied. – The Paramagnetic Croissant May 16 '16 at 06:19
  • 1
    @TheParamagneticCroissant, good point in general. For this specific case, the implicitly declared move constructor is deleted since the OP has a copy constructor, at least that's my understanding. – R Sahu May 16 '16 at 06:24
  • Yes, I'm not trying to nitpick, just added this since OP might be interested in knowing that in case s/he encounters a movable type in the future. – The Paramagnetic Croissant May 16 '16 at 06:25
  • @TheParamagneticCroissant ITYM that if NRVO is *not* applied then this calls the move constructor if present . (If NRVO applies then no constructor happens) – M.M May 16 '16 at 06:35
  • @RSahu There is no implicitly generated move constructor (if OP didn't declare one that he's hiding of course). – M.M May 16 '16 at 06:36
  • @M.M, http://en.cppreference.com/w/cpp/language/move_constructor seems to indicate that the compiler will generate a move constructor if certain conditions are met. – R Sahu May 16 '16 at 06:41
  • @RSahu one of the conditions is "there are no user-declared copy constructors;", but OP declared a copy-constructor – M.M May 16 '16 at 06:42
  • @M.M, we are on the same page on this. – R Sahu May 16 '16 at 06:43
  • @RSahu you said "the implicitly declared move constructor is deleted", which is false. There is no implicitly declared move constructor. "No function" is different to "Deleted function". – M.M May 16 '16 at 06:44
  • @M.M, I see your point. Thanks for the clarification. – R Sahu May 16 '16 at 06:48
  • @M.M Yes, you are right, I meant that. – The Paramagnetic Croissant May 17 '16 at 06:13
-1

You don't have to write a CC on C++. The compiler should give you one. And yes, a CC will be invoked in this case since you are trying to pass the return value as a copy.

Bhupesh
  • 209
  • 1
  • 5
  • The default cc wouldn't work in this particular situation because I had to have some pointers initialised. – developer10 May 16 '16 at 06:24
  • You shouldn't downvote this because you have not shown the complete implementation of the class and what I said holds completely true. If your class had attributes which don't have CC defined on them, that's the reason you would need to specify one while using one. – Bhupesh May 16 '16 at 15:50
  • It wasn't me who downvoted your answer. – developer10 May 16 '16 at 17:30