0

Why does this function print 4198400 ? My understanding was that since Bar is a child of Foo, it also has the member variable "a", and since changeA(b) sets a to 6, its should print 6.

#include <iostream>
using namespace std;

class Foo {
public:
    int a;
};
class Bar: public Foo {
public:
    int b;
};
Foo changeA(Foo f) {
    f.a = 6;
    return f;
}
int main() {
    Bar b;
    changeA(b);
    cout << b.a << endl;
    return 0;
}
CVDH
  • 5
  • 2
  • 1
    You are passing `f` by value and not by reference. So `b.a` has an indeterminate value and thus [using it is undefined behavior](http://stackoverflow.com/a/23415662/1708801). – Shafik Yaghmour Dec 08 '15 at 02:42

2 Answers2

1

Seems you're rather new at this so I'll try to see if I can explain. The fixed code that would work would look like this:

#include <iostream>
using namespace std;

class Foo {
public:
    int a;
};
class Bar: public Foo {
public:
    int b;
};
Foo *changeA(Foo *f) {
    f->a = 6;
    return f;
}
int main() {
    Bar *b = new Bar();
    changeA(b);
    cout << b->a << endl;
    return 0;
}

The problem with what you were doing was that when you pass b into that function, it passes a copy of it. Whereas you want to modify the original object itself. To elaborate on this, a copy of b is created and passed into that function, that function modifies it and returns it. so if you were to do a

Foo a = changeA(b);

That a would have the modified value that you want. but the original object would be left unchanged.

When you pass it as a pointer, the changes you will make within the changeA function will be applied to the original b as well. This same thing can also be achieved by using a reference (&), and It would be a lot easier:

#include <iostream>
using namespace std;

class Foo {
public:
    int a;
};

class Bar: public Foo {
public:
    int b;
};

Foo changeA(Foo &f) {
    f.a = 6;
    return f;
}
int main() {
    Bar b;
    changeA(b);
    cout << b.a << endl;
    return 0;
}

Here, You literally make one change and it will work, what the ampersand does is ensure that the you don't create a copy and pass that into the function, and pass the object itself instead. So this way, all changes are made to the original object itself.

Robin Singh
  • 161
  • 1
  • 5
0

If you need to change the values of Bar b inside changeA function there are two things you can do

  1. Pass existing instance(b) to the changeA function by reference and ask function to change the same instance.

    Foo changeA(Foo& f) { f.a = 6; } int main() { Bar b; changeA(b);
    return 0; }

  2. Pass the existing instance by value to the changeA by value and ask function to return the changed instance. Here you have to save the return value in a new instance.

    Foo changeA(Foo f) { f.a = 6; return f; } int main() { Bar b; Foo c = changeA(b); cout << c.a << endl;
    return 0; }

But, I like the first way because it avoid creating extra instance.

Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147