-5
#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();
    return 0;
}

I have trouble working this out. I am getting confused on how *val gives an output of 22 for both object.

Tavian Barnes
  • 12,477
  • 4
  • 45
  • 118
  • 1
    Have you stepped through the code with a debugger? – Bob Jarvis - Слава Україні Oct 25 '14 at 00:06
  • There is no memory leak in the copy constructor, but there should be a `delete` in the destructor. – Jim Buck Oct 25 '14 at 00:13
  • I'm not sure why this is being downvoted unless people feel this is a homework question, in which case, it should be tagged as such rather than downvoted. It's a non-trivial sample for those learning the subtleties of C++. – Jim Buck Oct 25 '14 at 00:19
  • Unless it's because of the duplicate? In which case, the dupe has a totally wrong answer marked as correct. – Jim Buck Oct 25 '14 at 00:20
  • 1
    @Deduplicator I believe the comma in the declaration marks a sequence point. Relevant finding: http://stackoverflow.com/questions/6414030/is-the-comma-in-a-variable-list-a-sequence-point. – luk32 Oct 25 '14 at 00:24
  • For those marking this as a duplicate, the linked-to question has an incorrect answer marked as correct.. not only that, the premise is false (the output is not 21). If anything, this question should "overwrite" the old question and not vice-versa. – Jim Buck Oct 25 '14 at 07:15

2 Answers2

2

b = a calls the initializer constructor (A(A &a)) for b using a, which gives both a and b a val of 1 (due to the get affecting a's val as well as returning that same value to initialize b's val). Then calling get in the cout statement turns both a's and b's vals to 2 and returns the 2.. and they print right next to each other, hence the 22.

Jim Buck
  • 20,482
  • 11
  • 57
  • 74
  • BTW: That ctor accepting an `A&` is a really bad idea. As is the absolutely useless allocation/indirection (leak inclusive). – Deduplicator Oct 25 '14 at 00:29
  • You mean it should be a `const A&`? If so, then definitely. Generally, this is clearly a homework question, so the unneeded allocation is merely to illustrate a non-trivial concept in C++. – Jim Buck Oct 25 '14 at 07:13
  • @Deduplicator Umm... It had to be non-const reference for it to "work" (as `get` is non-const *[I won't comment on that xD]*). Ofc it's a bad idea under normal circumstances. IMO whole `A` class looks like a bag of bad ideas. One not mentioned is violation of rule of three. But as Jim, I treat it as a thought experiment/exercise. Though, I really hope the example was put in a proper context, i.e. "Kids, never do it at work/home". – luk32 Oct 25 '14 at 10:16
  • @luk32: Yes, I know. Thanks for expanding on it. – Deduplicator Oct 25 '14 at 14:26
  • Hah, true, probably better for `val` to be `mutable` so that the constructor can be a `const A &`, but, yeah, it's a "bag of bad ideas" to be sure. If this is, in fact, a homework assignment, I would advise to lash the teacher/professor about some of the badness of `A` other than what was done purely for purposes of the homework. The teacher might need some......schooling....himself/herself. ;) – Jim Buck Oct 26 '14 at 03:43
0

It's simple. You create a which has *val set to 0.

Then you create b via b = a, which invokes copy constuctor. The copy constructor calls a.get().

A::get() increments the value pointed by val by 1 and then returns it. So a gets *val set to 1, and b gets back this value and also sets its own *val to 1.

Then you print both by using get() which again increases each before returning. So you get 2 from both gets on cout << a.get() << b.get();.

I don't know the reason why val is a int* instead of just int it only obfuscates the code, and makes it harder to grasp for a beginner.

luk32
  • 15,812
  • 38
  • 62
  • Due to this identical example showing up in other questions, it looks like a homework question to see if people understand that `b = a` is calling the copy constructor, thus creating a new `int` for `b` versus doing a bitwise copy via the non-overridden `operator =`. – Jim Buck Oct 25 '14 at 00:16
  • Oh, I didn't see identical question. Hmmm... makes sense. I though it's about the general grasp of semantics, which would also be valid IMO. I had to think for a bit what is going on =). I actually like such questions. Bummers, I thought it's a legitimate question to help understand how things work. – luk32 Oct 25 '14 at 00:19
  • @JimBuck: Identical question from the same account four weeks ago. Weird... – Blastfurnace Oct 25 '14 at 00:20
  • Oh, hah, I didn't notice the identical username.. well, he marked the answer in the dupe, though the answer is 100% wrong. – Jim Buck Oct 25 '14 at 00:21