1

I'm confused about the code following, I cannot figure out why Test t as parameter in calc and return t will call Test(Test &t)? Can anyone help me to make it clear? Thanks a lot!

#include <iostream>
using namespace std;

class Test {
  public:
    Test(int na, int nb) {
        a = na;
        b = nb;
    }

    Test(Test &t) {
        a = t.a + 1;
        b = t.b + 1;
    }

    int getValue() {
        return a + b;
    }

    Test calc(Test t) {
        return t;
    }
  private:
    int a;
    int b;
};

int main() {
  Test t(1, 1);
  cout << t.calc(t).getValue() << endl;
}
CYB
  • 1,106
  • 15
  • 36

1 Answers1

5

In the line

cout << t.calc(t).getValue() << endl;
        ^^^^^^^^^
           here

you pass t by value, not by reference (look again at the declaration Test Test::calc(Test t)) , so the argument t is being copied. The copy means an invocation of the copy constructor

Test(Test &t)

Same idea for the return t; - the (local) object being returned is copied from the local stack of the function to the return location destination.

BTW, you probably want a const for the copy ctor,

Test(const Test &t)

as in general you won't want to modify the source. Although technically you can have a copy ctor that takes its argument as non-const, see e.g. Can a copy-constructor take a non-const parameter?.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thanks for your quick reply and I can figure out what you said about `calc(t)`; however, why `return t` also triggered copy constructor ? I think it should be as same address as `Test t` from `calc` ? – CYB Dec 12 '16 at 14:52
  • oh ! The function needs to return a `Test` object, so it copied again! Is this correct ? BTW, thank you so much !! – CYB Dec 12 '16 at 14:54
  • 2
    @CYB Yes, that's indeed correct. Lots of copies are being made. However, in many instances (not in this case though, see the link) the compiler is allowed to perform what's called ["return value optimization (RVO)"](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) to elide those copies. With gcc or clang, if you pass `-fno-elide-constructors` you can disable this optimization so you can see all the copy constructors in action. – vsoftco Dec 12 '16 at 14:56