0
class A {
public:
    A(void) { cout << "A::A" << endl; }
    A(const A& a) { cout << "A::A(a)" << endl; }
    virtual ~A(void) { cout << "A::~A" << endl; }
    virtual void g(void) { cout << "A::g" << endl; }
};

class B : public A {
public:
    B(void) { cout << "B::B" << endl; }
    ~B(void) { cout << "B::~B" << endl; }
    void g(void){ cout << "B::g" << endl; }
};

void print(A c) {
    cout << "print" << endl;
}

int main(void) {
    A a;
    B b;
    A* c = &b;
    c->g();
    print(*c);
    return 0;
}

I don't understand why this statement A::A(a) get's executed when calling c->g() or print(*c);

And I'm not quite sure to which part of the programm does the Method print belongs to?

Chiel
  • 6,006
  • 2
  • 32
  • 57
LenC
  • 69
  • 1
  • 10
  • `print` is not a method, it's a free function. It belongs to the same "part" as `main`. "A::A(a)" is not printed when you call `c->g()` in this program. (And, to be picky, `"A::A(a)"` is not a statement.) – molbdnilo Mar 23 '16 at 10:20
  • Your `print` takes the argument by value, so a copy needs to be made. – Kerrek SB Mar 23 '16 at 10:23
  • You are passing by value to `print` function. As a result the copy constructor `A::A(const& A)` gets invoked. – Vishal Mar 23 '16 at 10:24
  • 1
    Are you *sure* the copy constructor is called when you do `c->g()`? I kind of doubt that. Can you please edit your question to include the exact output? You might also want to add more debug outputting between the variable declarations and the statements, to distinguish between the different outputs from the `A` and `B` classes. – Some programmer dude Mar 23 '16 at 10:25
  • My guess is that he's misinterpreted `A::A()` being called when constructing a `B`, and attributed that to the call of `c->g()`. Which, if true, means he needs to examine the output more closely. – Peter Mar 23 '16 at 10:54
  • Hello molbdnilo and Joachim Pileborg, yes you are right. ""A::A(a)"" is not printed when I do c->g(). I missed it. Thanks for all the answers :) – LenC Mar 23 '16 at 16:58

2 Answers2

3

Since you pass the argument by value to the print function, a copy must be made using the copy constructor. That is why your copy constructor is called when print is called.

If you change to call be reference (or by passing a pointer) then no copying will be made.


And as stated by others, print is a "normal" function, also known as a "free" function, or a non-member function. It "belongs" to the program, and exist in the global scope and have external linkage.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

Print isn't a method, it's a function, as such it doesn't "belong" anywhere - it's simply part of your program. Functions are from the age before Object-Orientation, though still have an important place.

The void print(A c) Function can be broken down as follows:

  1. void, this is the return value, in this case - nothing.
  2. print(, this is the name of the function.
  3. A c), this means it will take a single parameter of type A, named c.

As such A::A(const A &) is the copy constructor of the object A; Essentially this method will be called Every time an object of type A is copied into a new object of type A

When you call print(*c), you derefrence The pointer c, this results in a reference to the object pointed to by c (ie: an object of type A). This is then copy constructed into the print function, resulting in a temporary const A & that is used by the function.

This is why the Copy-constructor is called.

Community
  • 1
  • 1
John Bargman
  • 1,267
  • 9
  • 19