Classes and inheritance question Help!

Hi, I don't know why the output is 22 instead of 12.
can someone explain me the lines that made it 22?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   #include <iostream>
    using namespace std;
    
    class A { 
        int *val;
    public:
        A() { val = new int; *val = 0; }
        A(A &a) { val = new int; *val = a.get(); }
        int get() { return ++(*val); } 
    };
    
    int main() {
        A a,b = a;
        cout << a.get() << b.get();  //  from what I learned, a.get() will output 1 and b.get() will output 2..Or, is it because since a,b=a hence a.get() is converted to 2 hence outputing 22?? is it right?
        return 0;
    }
 
The output is actually undefined. It can be either 11 or 22, but not 12. I'll explain them both.

You're getting 22 because b = a calls the copy constructor A(A &a). This allocates a new val and then executes
*val = a.get();
a.get() increments *a.val to 1 and returns 1 (note that it's a pre-increment operator. Could that be the source of confusion?). Then *val = a.get() assigns 1 to *val.

So when you're done with line 13, a and b are both 1. Then line 14 calls the get() method on each one, which increment the value to 2 and return 2.

So why can it be 11 also? Because b = a; can be implemented in two ways and the compiler is free to pick either one. It can call the copy constructor (which it's doing here) or it call the default constructor followed by the assignment operator. In other words, it can do it like this:
1
2
A b;
b = a;

If it did it like this then get() would not be called and both both *a.val and *b.val would contain 0 at the end of line 13. Line 14 would then increment both values to 1 and output 11.

This is why you should always define a default constructor and assignment operator if you define a copy constructor, and vice versa.

One more note: you should define a destructor that deletes val to avoid a memory leak.
a.get() is called twice so final a->val equals 2
b.get() is called once, but initial b->val equals 1, thus final b->val equals 2
Last edited on
> If it did it like this then get() would not be called
> and both both *a.val and *b.val would contain 0 at the end of line 13.
> Line 14 would then increment both values to 1 and output 11.
If it called the assignment operator, then `b.val' and `a.val' point to the same location.
Line 14 would be undefined behaviour (order of evaluation)

> I don't know why the output is 22 instead of 12.
¿why do you think it should be 12?


¿how does inheritance relate?
Last edited on
Topic archived. No new replies allowed.