Where is my base created? - c++

If I have:
struct Base
{
};
struct Derived : Base
{
};
And I create Derived in main:
Derived* d = new Derived;
where (on heap or on stack) is my base created? Am I reasoning correctly that a Base is a part of a Derived so it is created wherever Derived is created? Or does it work in some other way?

The base class contribution is generally part of the derived object (and so uses part of the object's memory along with the derived portion). Your example can make this irrelevant, however, because the base class portion takes up zero memory due to the C++ empty base class optimization.
Despite the fact that the derived struct is empty as well, the final object must be at least one byte in size, because all objects must take up space, to ensure that the addresses of two different objects will be different. See: Why is the size of an empty class not zero? for more info.

The Base is created in the same memory segment as the Derived. In your example, since you allocate Derived on the heap, the Base is also allocated on the heap. They form one contiguous object in memory.

Related

when allocating memory to an object of base class, does the memory for the derived class is allocated too?

class A {
private:
int _a;
public:
//some virtual methods...
};
class B : public A {
private:
int _b;
public:
//methods..
};
when declaring a pointer of type A like:
A* a = new A();
does the vtable created fits the size of both ints a and b or does the space allocated fits only an object of type A?
Of course not!!
The class A does not know of the existence of class B
But class B inherits A so it does indeed know A
In other words, what it happens is the opposite:
The memory space allocated when creating an instance of class B is enough to hold the members of class B and the inherited members of class A
You create an object of type A. So the memory will be allocated for this type of object. It will large enough to contain int _a and vptr. I think if the size of pointer is equal to 4 then 8 bytes will be allocated for an object of type A.
You should understand that base classes know nothing about what derived classes will be defined based on the base classes.
However if you would write
A* a = new B();
then an object of type B would be created in memory. But the static type of pointer a is A *. So you could not access data member _b without dynamic_cast or static_cast pointer a to type B *.
Class A doesn’t know about its derived classes (they might be physically completely separate, in other compilation units, loaded later at run time). Even if it did, there’s no sense in allocating space for all its derived classes – because it is not its derived classes.
Just like parents don’t go to school for their children, a class does not act in its derived classes’ stead.
does the vtable created fits the size of both ints a and b or does the space allocated fits only an object of type A?
These members do not go into the vtable anyway. As for members which do go into the vtable (= virtual functions), the above applies: a base class’ vtable is only big enough for the virtual functions it declares, and no others.
Only A.
Otherwise A would grow when someone creates new classes: C, D, E, ... all of them deriving from A. This would be absurd.
It doesn't create a vtable - there's (typically) just one of those per class. It creates an object, of type A with enough space for the member(s) of A. It doesn't create an object of type B (or anything else) since that's not the type specified by the new expression.
NO and the reason is really simple:
A class does not contain any of B class members or methods.
=> So, memory space for B is not necessary

Instanceof for objects in c++ (not pointers)

If I have the following classes :
class Object { ... }
class MyClass1: public Object { ... }
class MyClass2: public Object { ... }
and a stack : std::stack<Object> statesObjects;
MyClass1 c1;
MyClass2 c2;
statesObjects.push(c1); // okay
statesObjects.push(c2); // okay
How can I pop them out and retrieve the element at the head of the stack (with top() ) without dynamic_cast , since I don't work with pointers here ?
The short answer is, that with your stack as-is you can't pop out the elements as derived-class type elements. By putting them into the stack you have sliced them to the element class of the stack. That is, only that base class part has been copied into the stack.
You can have a stack of pointers, however, and then you can use dynamic_cast provided that the statically known class has at least one virtual member function, or as the standard says, provided that the statically known class is polymorphic.
On the third and gripping hand, however, instead of the Java-like downcast use a virtual function in the common base class. Often it works to just directly have such a function. For more complicated scenarios you may have to use the visitor pattern (google it), but basically, the idea is that virtual functions are the “safe” language-supported type safe way to achieve the effect of downcasts.
You cannot pop them out to their original classes, when you assign a subclass to an instance of the superclass, it gets sliced into an instance of the superclass. i.e copies of c1 and c2 which are in the stack are now instances of Object and not their original classes
Similar to How can I make the method of child be called: virtual keyword not working?
Even if you seeminlgy store a derived class object in your class, what gets stored is only the Base class part of the object. In short You get Object Slicing.
To summarize, you cannot store derived class objects in this container. You will need to store a pointer to Base as the type of conainter and use dynamic polymorphism to acheive this.
Good Read:
What is object slicing?

Memory allocation of base class and derived class constructor

For which one the space is allocated first when the derived class object is created?
whether base class constructor or derived class constructor?
First,
allocation, the reservation of memory which you’re asking about, is different from and precedes initialization (execution of a constructor that essentially sets suitable values in that memory), and
the formal (our Holy Standard) and the in-practice differ on whether memory for a most derived object needs to be contiguous, with the formal defining a “region of memory” as possibly non-contiguous, mostly in order to support multiple virtual inheritance.
That said, in practice a most derived object is a single, contiguous chunk of memory that includes space for all base class sub-objects and data member sub-objects, and this chunk is necessarily allocated all at once.
Initialization (calls of constructors) proceeds after the allocation. A new expression guarantees a deallocation if initialization fails by throwing an exception. However, this guarantee is voided if the allocation function that’s employed has extra custom arguments (a so called “placement new”) and no corresponding deallocation function is available, as was the case e.g. for debug builds in early versions of Microsoft’ MFC class framework (it was pretty ironic: a program where initialization failed would leak memory only in debug builds…).
The space for the derived object holds all of the derived members and all of the base members. There is only one allocation for the derived object, and the allocated memory holds all the pieces of the object.
As mentioned in the comment it is the Base class. Logically, since you can access the base public and protected members in the Derived class (including constructor) it will need to be allocated first. Try starting with the following code and play around.
#include <iostream>
class Base
{
public:
Base() {std::cout<<"Base CTOR" << std::endl;}
};
class Derived : public Base
{
public:
Derived():Base() {std::cout<<"Derived CTOR"<<std::endl;}
};
int main(int argc, char* argv[])
{
Derived d;
}

Get address of base object from derived object

I'm getting a very confusing error in my program. I think I may have two different objects of the same class where I thought I had the same object. It is confusing because I am dealing with a very large framework where it is not simple to obtain a pointer to the object I need.
My question is, if I have a class Derived which in inherits from Base, and I have a pointer to a Derived object, how can I get the address of the Base object from the derived object? I am working with the source code of the Base Class and am printing out the address of "this" in Base. In another part of my code a retrieve a pointer to a Derived. I need to be able to print the address of the Base object via my Derived object to determine whether I have a pointer to the particular Derived object I need.
I may have a great misunderstanding of how the addresses work in C++ in inheritance. Perhaps their is only one object, not a base object linked to a derived object?
Thank you very much
Edit:
The reason I want to do this is purely for debugging. The problem is that the code base I'm using does not contain many interfaces or protected members, so I am having to edit the source code to access a certain piece of information. However, my program crashes when I call a method I added to the Base class using a specific Derived pointer. I need to be able to print the address of the base object in this case so that I can determine whether this is the correct object or whether I am getting this error because I actually have a pointer to the wrong object. I realize I can add code to the derived class to cause it to print its address, but I was just wondering if it was possible to get the address without editing the source code any more. Thanks
Going from a pointer to derived class to a pointer to a base class is easy:
Derived * derived_ptr = < some pointer >;
Base * base_ptr = derived_ptr;
If you want to be pedantic, you can use static_cast on the right hand side of the assignment:
Base * base_ptr = static_cast<Base*>(derived_ptr);
Going from a pointer to a base class to a pointer to a derived class uses dynamic_cast:
Derived * derived_ptr = dynamic_cast<Derived*>(base_ptr);
However, this won't always work. You need to have run-time typeid enabled and the base class needs to have at least one virtual method.
Before you go doing this, why do you need to go from a base pointer to a derived pointer? That is a clue that you may need to rethink your design.
There is only one object, it is composed of a Base and a Derived- that is, the Base is put into memory right next to the Derived, in most implementations. That means that the Base* is not the same as Derived* in the general case, but they will be very close.
Now, you can trivially obtain the Base* from the Derived*, the cast is implicit, but you can also make it explicit:
Derived* dptr = ...;
Base* ptr = dptr;
However, there is nothing stopping a single derived object from containing multiple Base objects. Usually this is not the case, but it can happen. That means that you cannot compare Base pointers and expect to know if you are dealing with the same object, only the same Base subobject.
In the simple case of single inheritance, with most compilers:
If you've got a pointer to the derived class, then that's the same as the pointer to the base class. Both pointers have the same value and point to the same memory address.
In memory, if you create an instance of a derived class, it will be laid out as the members of the base object, followed by the members of the derived object. The base class members form part of the derived object.
class Base
{
int b;
};
class Derived : public Base
{
int d;
};
In memory, say the Derived pointer is 0400. Then:
0400 byte 1 of b
0401 byte 2 of b
0402 byte 3 of b
0403 byte 4 of b
0404 byte 1 of d
0405 byte 2 of d
0406 byte 3 of d
0407 byte 4 of d
The derived object consists of the base members and derived's own members, and the address of both of these starts at 0400.
It just so happens, that at 0400, the base object part of derived is located. So, base and derived have the same address.

Declaring pointer to base and derived classes

I just found that I am confused about one basic question in C++
class Base {
};
class Derived : public Base {
}
Base *ptr = new Derived();
What does it mean? ptr is pointing to a Base class or Derived class? At this line, how many memory is allocated for ptr? based on the size of Derived or Base?
What's the difference between this and follows:
Base *ptr = new Base();
Derived *ptr = new Derived();
Is there any case like this?
Derived *ptr = new Base();
Thanks!
For Base *ptr = new Derived(); memory is allocated according to Derived class. ptr points to the object but the compiler is instructed to only "grant access" (visibility) to the members of the object that are declared in the Base class.
Of course the memory associated with the pointer ptr is the same i.e. independent of the object it is instructed to point to. Usually, the size of a "pointer object" is constant on a CPU architecture e.g. 32bits / 64bits (or smaller on embedded devices for example).
For Derived *ptr = new Base();: no, this is invalid.
Class Derived isn't just a class Base but is defined as deriving from Base: hence, a pointer instance to a Derived object instance can't be just assigned to an object instance of class Base.
You might consider perusing the very good Wikipedia contributions on Polymorphism and Inheritance.
Polymorphism
ptr is a pointer; it has the same size regardless of what it points to.
On a 32-bit system, 4 bytes of stack space are allocated for ptr. On a 64-bit system, it would be 8 bytes. (Assuming that the compiler doesn't decide to leave it in a register and not allocate any stack space at all).
The reason you can let a pointer to a Base point to a Derived is one of the basic principles of OOP - polymorphism. A Derived is a Base. You can stick it in anywhere a Base could be used.
Your last line (Derived *ptr = new Base();) is invalid because a Base is not a Derived.
To understand the type system of C++, its important to understand the difference between static types and dynamic types. In your example, you defined the types Base and Derived and the variable ptr which has a static type of Base *.
Now when you call new Derived(), you get back a pointer with a static and dynamic type of Derived *. Since Derived is a subtype of Base this can be implicitly converted to a static type of Base * and assigned to ptr as the static types now match. The dynamic type remains Derived * however, which is very important if you call any virtual function of Base via ptr, as calling virtual functions is always based on the dynamic type of the object, not the static type.
Your question hits on one of the most important parts of object-oriented programming: polymorphism.
Derived is a subtype of Base. That means that everything that Base can do, Derived can also do. Often, Derived is more specific than Base: it works on a subset of what Base does, but it does that subset much better than what Base does.
Think about an example.
Think about writing a graphics program. You might have a class, ClosedShape, and a method inside it, fill(). It's possible to create a very generic method that can fill any closed shape... but usually, that method will take memory, and it might be slow.
You might have another class, Square. Now, filling squares is very easy and very fast: it's two nested for loops. Since Square does everything that ClosedShape does, it can inherit from ClosedShape.
Why is polymorphism important? Think about many different kinds of ClosedShape: triangles, hexagons, and so forth. If you want to fill all of them, just do:
for (i=0; i<num; i++) {
cs[i].fill();
}
They all will use their own version of fill()!
For Base *ptr = new Derived(); memory is allocated according to Derived class. ptr points to the object but the compiler is instructed to only "grant access" (visibility) to the members of the object that are declared in the Base class.
Of course the memory associated with the pointer ptr is the same i.e. independent of the object it is instructed to point to. Usually, the size of a "pointer object" is constant on a CPU architecture e.g. 32bits / 64bits (or smaller on embedded devices for example).
For Derived *ptr = new Base();: no, this is invalid.
Class Derived isn't just a class Base but is defined as deriving from Base: hence, a pointer instance to a Derived object instance can't be just assigned to an object instance of class Base.
A Derived object is appended to the end of the Base object, so the prefix [in bits] of Derived is actually a Base, so there is no problems to assign a Derived* object to a Base* variable. It is perfectly safe to access any of Base's fields/methods of the Derived object.
However - the oposite is not true. If you assign the address of the Base* to a Derived* variable and then access one of the fields of Derived [which is not in Base] you will get out of the allocated space.
Typing reasoning:
Also note that a value can be assigned to a variable only if it is of the correct type without casting [c++ is static typing langauge]. Since Derived is a Base, Derived* is a Base* - so this is not conflicting, but the other way around is not true.
I highly recommend to read the comment to understand the logic as well