0

I try to understand the logic behind accessing members of a derived object. I have two pointers: If I change the variable in my derived class via a pointer to the derived class, I notice that I am not able to access the value of the variable via a inheritance type of pointer to the base class.

#include <iostream>
#include <string>

class A
    {
    public:
        int x;
    };

class B : public A
    {
    public:
        int y;
    };

int main()
    {
    B* pB = new B;
    A* pA = new B;

    std::cout<<"Changing x via pB to 11"<<std::endl;
    pB->x=11;
    std::cout<<"This is x: " << pB->x<<std::endl;
    std::cout<<"What about this x: " << pA->x<<std::endl<<std::endl;

    std::cout<<"Changing x via pA to 42"<<std::endl;
    pA->x=42;
    std::cout<<"This is my new x: " << pB->x<<std::endl;
    std::cout<<"and what about this x now: " << pA->x;

    delete pA;
    delete pB;
    }

Output:

Changing x via pB to 11
This is x: 11
What about this x: 0

Changing x via pA to 42
This is my new x: 11
and what about this x now: 42

I would like to know what has happens and why there are two different values for x. What also bothers me is that when I work, for example, with multiple lists: a master list with pointers to all my objects (say some animal class) and a secondary list--a sub-sample of the master list with pointers to some objects (say class reptile: public animal, public predator)--and it happens that I wish to modify the values of these members through the second list (bool is_currently_in_water), I cannot do this in a straightforward (and to me intuitive) way. I have to keep track of the master list and first find out which animal object is a reptile, in order to make the necessary changes through the master list.

Is polymorphism intended to be like this? This is perhaps a very basic question as I am a beginning to learn C++, and although I know how to overcome the problem my changing my code, I first trying to fully grasp what is going on as the above result was rather surprising.

CodeTrek
  • 435
  • 1
  • 3
  • 10

3 Answers3

2

I would like to know what has happens and why there are two different values for x.

The explanation is quite simple: you have two values of x because you have two separate objects of type B, referenced through two pointers pA and pB, which are completely independent of each other.

When you print pB->x you print x attached to the object that you have allocated first; when you print pA-X, you print x attached to the object that you have allocated second. These two objects do not share member variables, so their xs are independent of each other.

If you would like to see behavior when two pointers of different type refer to the same object, do this:

B* pB = new B;
A* pA = pB;

Now pA and pB are pointing to the same object, so any changes to x through one pointer would be "visible" through the other pointer. Of course, now that there is only one allocation, you need to remove delete pA (or delete pB if you prefer) to avoid double-deletion of the same object.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • that's it! That's what I wanted! Many thanks.. How stupid of me! I didn't noticed my mistake and my program was going well, until suddenly I was querying the strange behavior! Since you intuitively knew what I was trying to do, I will give you the vote (although you answered second).... :-) – CodeTrek Oct 12 '15 at 17:15
  • btw. how do I do that with shared_ptr? Getting strange error message here. – CodeTrek Oct 12 '15 at 17:28
  • @user2856452 This is a very interesting question to which SO has a couple of good answers( [1](http://stackoverflow.com/q/19102034/335858) and [2](http://stackoverflow.com/q/27109379/335858)). – Sergey Kalinichenko Oct 12 '15 at 17:32
0

There are 2 different values because you have 2 different objects:

B* pB = new B;
A* pA = new B;

The object pA points to has no relation whatsoever with the one pB points to. And, in the first

std::cout<<"What about this x: " << pA->x<<std::endl<<std::endl;

you are reading uninitialized data, which is undefined behaviour.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • That makes sense. Thank you! I wanted actually to make two pointers to the same object (but referring to different base classes) is that possible? – CodeTrek Oct 12 '15 at 17:14
0

You trying to read x from two different object.

If you want to refer to you object with the parent pointer you need to define a parent pointer like the following

B* pB = new B;
A* pA = pB;

Now if you change x from pointer pA, it will be changed on pB too.

Captain Wise
  • 480
  • 3
  • 13