0

I am having difficulty in understanding how we can store objects of derived type into pointer of base type.

class Base
{
    int a;    // An object of A would be of 4 bytes
};

class Derived : public Base
{
    int b;    //This makes Derived of 8 bytes
};

int main()
{
    Base* obj = new Derived();    // Is this consistent? I am trying to store objects of Derived type into memory meant for Base type
 
    delete obj;

    return 0;
}

I see this format being used extensively for achieving run-time polymorphism. I am just wondering if there is a way to access non-inherited data members (b in this case) of Derived object using obj.

Does doing Base* obj = new Derived(); result in object slicing? If so, why is this model prevalent for achieving polymorphism?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Kshitij_9192
  • 37
  • 1
  • 7
  • If you're talking about polymorphism, you should be dealing with code example that uses polymorphism. – fana Oct 19 '22 at 04:01
  • 1
    For `Base* obj = new Derived();`, the static type of `obj` is `Base*`, and the dynamic type of `obj` is `Derived*`. – fana Oct 19 '22 at 04:05
  • Yes, use a virtual function defined in Base and overridden in Derived. – n. m. could be an AI Oct 19 '22 at 04:49
  • Be careful with terminology. The code is **not** storing **objects** of Derived type. It is storing a **pointer** to an object. There are no `Base` objects in this code. There is one `Derived` object, created by `new Derived()`; its **address** is stored in the pointer named `obj`. The `Derived` object has a `Base` sub-object; the `new` handled all of the memory requirements for that. – Pete Becker Oct 19 '22 at 13:13
  • Thanks @Pete Becker for clarifying this. I chose my words wrongly. I was just wondering whether b would be accessible using obj as it is. – Kshitij_9192 Oct 19 '22 at 15:24

1 Answers1

0

I am just wondering if there is a way to access non-inherited data members (b in this case) of Derived object using obj.

Not when using obj as-is by itself, because b is not a member of Base.

But, IF AND ONLY IF obj is pointing at a Derived (or descendant) object, you can type cast obj to a Derived* pointer in order to directly access members of Derived.

Otherwise, another option is to define a virtual method in Base that Derived can override to access its own members as needed. You can then call that method via obj as-is.

Does doing Base* obj = new Derived(); result in object slicing?

No. A Derived object is also a valid Base object, so obj is simply pointing at the Base portion of the Derived object. Object slicing occurs when you assign an instance of a derived class to an instance of a base class, in which case only the base portion can be assigned. But assigning a pointer to another pointer does not assign the objects that they are pointing at.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks @Remy for your answer. It clarified a lot of things for me. Also I performed a static_cast on obj to convert it to Derived* type and indeed I was able to access member b via it. – Kshitij_9192 Oct 19 '22 at 06:13
  • @Kshitij_9192 use `static_cast` only when you KNOW FOR SURE that `obj` points at a specific type. If you DON'T KNOW FOR SURE, use `dynamic_cast` instead, and test the result for failure before using it. – Remy Lebeau Oct 19 '22 at 06:31
  • Thanks Remy for the note. That was quite helpful and I will remember this. – Kshitij_9192 Oct 19 '22 at 07:14