Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More than 1 address for derived class object?

In Item 27 of "Effective C++" (3rd Edition, Page 118), Scott Meyers said:

class Base { ... };
class Derived: public Base { ... };
Derived d;
Base *pb = &d;

Here we're just creating a base class pointer to a derived class object, but sometimes, the two pointers will not be the same. When that's the case, an offset is applied at runtime to the Derived* pointer to get the correct Base* pointer value.

This last example demonstrates that a single object (e.g., an object of type Derived) might have more than one address (e.g., its address when pointed to by a Base* pointer and its address when pointed to by a Derived* pointer).

Here is a bit hard to understand. I know that a pointer to the base class can point to an object of the derived class at runtime, this is called polymorphism or dynamic binding. But does the derived class object really have more than 1 address in the memory?

Guess I have some misunderstanding here. Could someone give some clarification? Maybe this has something to do with how polymorphism is implemented in the C++ compiler?

like image 423
Qiang Xu Avatar asked Feb 08 '13 15:02

Qiang Xu


People also ask

What is a derived class object?

Derived Class: A class that is created from an existing class. The derived class inherits all members and member functions of a base class. The derived class can have more functionality with respect to the Base class and can easily access the Base class. A Derived class is also called a child class or subclass.

What is the size of the object of derived class?

If compiled with the Microsoft C++ compiler, the size of DerivedClass is 16 bytes. If compiled with gcc (either c++ or g++), size of DerivedClass is 12 bytes.

Can we assign derived class object to base?

In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

Can you assign the address of an object of a derived class to a pointer to the base class?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.


2 Answers

Just try it:

class B1
{
    int i;
};

class B2
{
    int i;
};

class D : public B1, public B2
{
    int i;
};

int
main()
{
    D aD;
    std::cout << &aD << std::endl;
    std::cout << static_cast<B1*>( &aD ) << std::endl;
    std::cout << static_cast<B2*>( &aD ) << std::endl;
    return 0;
}

There's no possible way for the B1 sub-object to have the same address as the B2 sub-object.

like image 136
James Kanze Avatar answered Oct 02 '22 01:10

James Kanze


An object has exactly one address; that's where it's located in memory. When you create a pointer to a base subobject you get the address of that subobject, and that doesn't have to be the same as the address of the object that contains it. A simpler example:

struct S {
    int i;
    int j;
};

S s;

The address of s will be different from the address of s.j.

Similarly, the address of a base subobject does not have to be the same as the address of the derived object. With single inheritance is usually is, but when multiple inheritance comes into play, and ignoring empty base classes, at most one of the base subobjects can have the same address as the derived object. So when you convert a pointer to the derived object into a pointer to one of its bases you don't necessarily get the same value as the address of the derived object.

like image 25
Pete Becker Avatar answered Oct 02 '22 02:10

Pete Becker