I'm assuming that my base class has one "int" member and the derived class has also one "int" member. Now when I create one derived class object and see the output by sizeof(derivedClassObject) then it is becoming 8. Now I am troubling to grasp the underlying idea here.
I know that when I create an object for the derived class then both the base class constructor and derived class constructor are get called. The only purpose of base class constructor here is to initialize the base class data members. I expected that the sizeof will display 4 because I am only interested to create a derived class object. But instead of that I am getting output as "8". So, extra 4 byte is being allocated and I think its happening for the base class constructor. I would appreciate if anyone help me to grasp the following concepts:
Why 8 bytes are being allocated instead of 4 when I create a derived class object? Does it mean that base class constructor is also creating a new base class object and concatenating it with the new derived class object?
I am just creating one derived class object and the size of that derived class object is: sizeof(baseClassObject) + sizeof(derivedClassObject). I would really appreciate to get some help.
In general inheritance in oop means that an object of a derived class is also an object of the base class. Therefore it contains everything the base class contained (in this case one int, so 4 byte) and any additional data members from the derived class (so another int).
If that wasn't the case, how would an object of the derived class be usable as an object of the base class? Inherited methods would likely do horrible things, since the data members they are trying to access wouldn't exist.
Therefore the sizeof(derivedClass)==sizeof(baseClass) + sizeof(int) (although nothing is keeping the compiler from making it bigger).
If you don't want your derivedClass to be usable as a baseClass you shouldn't derive from it.
Assume you have two classes as below
class Car {
int make;
public:
Car(int m): make(m) {}
int getMake() { return make; }
};
class Audi : public Car{
int internalID;
public:
Audi(int m, int id): Car(m), internalID(id){}
int getInternalID() { return internalID; }
};
Now I go ahead and create an object of Audi
Audi *myCar = new Audi(2012 /*make*/, 216487 /*internal ID*/);
you can do something like
myCar->getInternalID(); //returns 216487
myCar->getMake(); //returns 2012
If your assumption that creating the derived class should allocate space only for derived members, where would 'make' be stored in this case?
A derived class is nothing but baseclass + members declared in derived class. Hence your derived object would look something like this in memory
------------
| make |
------------
| internalID|
-------------
Hence you get the size of derived class members plus size of base class. Again, size of base class will be size of base class members plus size of its base class. Hope this helps!
Related
So I want to know if its possible to create a certain derived class by constructing the base class with a certain argument. For example:
lets say;
class Base
{
Base::Base(char derived_selector){...};
}
class DerivedA: public Base
{
char id_;
DerivedA::DerivedA(char id):id_(id){};
}
class DerivedB: public Base
{
int id_;
DerivedB::DerivedB(int id):id_(id){};
}
Now the reason for inheritance from base here is not clear but since its an example I think it should be fine to understand the realtionship here.
What I want to achieve is when I call
Base *ptrA = new Base('A');
Base *ptrB = new Base('B');
The constructor makes the selection of the derived class for me and constructs a DerivedA object for ptrA, and a DerivedB object for ptrB.
I do think there could be some problems like how would the Base constructor know how to set the attributes of the derived class but I feel like it could be achieved somehow. Also if it is indeed possible would this be a good object oriented way or should just decide which one I am making with a simple if else statement when I am going to construct a derived class?
Can any explain why baseclass pointer cannot be assigned to derived class pointer? I know it is not possible ,but i like to know the reason .logically derived class contain base class.Let me know the reason
Thanks in advance
Consider:
struct A
{
};
struct B : A
{
int b;
};
struct c : A
{
char c;
};
C cobj;
A* aptr = &cobj;
B* bptr = aptr; // Assuming this were allowed...
bptr->b = 10;
By doing that you'd have used memory beyond what is valid. You have created an object of size sizeof(C) but not you are treating it like it is of size sizeof(B).
A derived class can have its own data members and member functions in addition to all of those within the base class.
If you point the derived class pointer to the same thing as a base class pointer, the derived class pointer will think it's pointing to a derived class object, even though it's pointing to a base class object.
If you try to access derived class data members or member functions using this derived class pointer, it won't work because it's pointing to a base class object that doesn't have these capabilities.
For instance, let's assume I have a base class called Person and a derived class called Programmer. I can make a Person object and have a pointer point to that object. I can then try to make a Programmer pointer point to that Person object as well (by setting it equal to the Person pointer). If I used my Programmer pointer to try and make the Person object code (equivalent to calling a Programmer member function) or do something only a Programmer does, it wouldn't work because the Person hasn't been specialized.
I assume your question is why following should not be done:-
Derived *ptr = new Base; //assume for now public inheritance.
Derived is specialization of Base i.e Derived would inherit all features of base plus it could also add some of its own features. That means assigning Base to Derived ptr leads to loss of those features which could result into undefined behavior if call is made to that variable/method.
#include<cstdio>
#include<iostream>
using namespace std;
class A
{
public:
int x;
};
class B: public A
{
};
int main()
{
B b;
b.x=5;
cout<<b.x<<endl;
return 0;
}
i have the above code.it's all okay.but i want to know when i inherit class B from class A does the member variable x declared in class B too just like A or the class B just get access to the member variable x of class A ?
are there two variables with the same name in two different classes or there are only one variable and the objects of the both classes have access to it ?
if there are two different variables with the same name in two different classes then why, when an object of derived class is declared the constructor of base class is called ?
When you create an object of the derived class, a base class sub-object is embedded in the memory layout of the derived class object. So, to your question, there's only on variable that will be a part of the derived object.
Since, we are only taking about non-static members here, each derived object gets its base-class sub-object laid out in memory.
When you create a base class object, its a different piece of memory representing different object and has nothing to do with derived object created earlier.
Hope it clarifies your doubt!
This is a great book to understand C++ object model:
http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545/ref=sr_1_1?ie=UTF8&qid=1412535828&sr=8-1&keywords=inside+c%2B%2B+object+model
I need help with a specific programming problem in C++ (not sure if this is even possible in C++). I need to be able to access all public member functions in Base class, but do not want to allocate memory for the Base class data while allocating the Derived class object.
Lets say, I have:
class Base
{
public:
Base();
~Base();
int GetFoo() { return foo; }
// other public member functions of Base class
private:
int foo;
// other data
};
class Derived : public Base
{
public:
Derived(Base *BasePtr);
Derived(Base &BaseRef);
~Derived();
double GetXyz() { return xyz; }
// other public member functions of Derived class
private:
double xyz;
// other data
};
Now, lets say I already have a Base class allocated and initialized. I want to create a new Derived class object by referring to that existing Base object and allocate memory only for the data specific to the Derived class. Following the above example, I would have already allocated memory for "int foo" in the Base class object and only want to allocate memory for "double xyz" in the Derived class object.
Base *basePtr = new Base();
Derived *derivedPtr = new Derived(basePtr); // what is the content of this function?
What should be the memory allocation or the constructor for the Derived class look-like? I want to inherit all data and member functions of the Base class, but without doing a "combined" data allocation of Base and Derived. I have tried overloading operator new but no luck. Any help is appreciated.
I'm not sure if it fits your requirements, but you could simply copy the contents of the Base stored in basePtr inside a new Derived object, then delete the Base object and point at the new Derived object with the old Base pointer. Like this:
Base *basePtr = new Base();
/* Do something with base here */
Derived *derivedPtr = new Derived(basePtr);
delete basePtr;
basePtr = derivedPtr;
derivedPtr = 0;
That way you'll end up with only one object (of type Derived) and won't have to store a separate pointer to it, nor store the Base object, and that seems like what you need.
Update:
in my case, I cannot delete the Base object since I would have created millions of them (using GigaBytes of RAM space) and people could be using pointers/references to those objects, so copying them to Derived objects and deleting the old Base objects doesn't work for me.
In that case, maybe you should try to do an "extendable* structural wrapper. First create an simple class without any method or member:
class Additional{};
Then create a wrapper structure:
struct wrapper{
Base *basePtr;
Additional *moreInfo;
}
Then, instead of deriving your Derived class from Base, derive it from Additional. And instead of storing milions of Base pointers, store milions of wrapper pointers. IT'll make your code a bit longer and harder to understand, but it'll do what you need. Well - unless the only thing your Derived class adds is a pointer or any data that takes less size.
If you've got virtual functions in Base, in order to use them with the new hierarchy, oyu'll just have to check every time:
wrapper *wrapperPtr = &alreadyCreatedSomewhereWrapper;
if(wrapperPtr->moreInfo)
wrapperPtr->moreInfo->function();
else
wrapperPtr->basePtr->function();
Use multiple inheritance.
class Base()
class Derive1() : Base
class Derive2() : Base
class MostDerive() : Derive1 , Derive2
MostDerived() will be thin. Derive1 and Derive2 will need to be deterministically constructed, but that can be imposed, or some Init() functions can be used.
Say i create a derived class as below,
class CHIProjectData : public QObject
{
CHIProjectData(QMap<QString,QString> aProjectData,
CHIMetaData* apMetaData = 0,
QObject* parent = 0);
private:
QMap<QString,QString> m_strProjectData;
CHIAkmMetaData* m_pMetaData;
};
and i implement like,
CHIProjectData::CHIProjectData(QMap<QString,QString> aProjectData,
CHIMetaData* apMetaData,
QObject* aParent)
:m_strProjectData(aProjectData),
m_pMetaData(apMetaData),
QObject(aParent)
{
}
i know i initiate the member variables m_strProjectData, m_pMetaData in the constructor. but what does the last part "QObject(aParent)" do? does it create an object of base class and consider that as a member variable?
QObject(aParent) calls QObject's constructor with the aParent parameter. QObject is not a member variable in this case. It may seem like a subtle point, but its an important one because the way you access the properties and methods of a subobject requires different syntax than as for a member variable.
Here's an analogy to try to understand the difference between a subobject and a member variable.
In the movie "Batman: The Dark Night" there is a scene where Batman is pursuing the bad guy in his car. But the car becomes damaged and unusable, and he has to escape. At that point Batman pushes a button and part of the car detatches from the rest, becoming a motorcycle. This is kind of like a subobject. The car is a motorcycle.
Now consider the case of an RV towing a smaller vehicle, the likes of which are frequently seen on the highways of America. In this case, the RV has a vehicle. The vehicle is a member variable of the RV.
Essentially, that is what is happening under the hood. The base class parts of your object, like its data members, are called subobjects.
The notion of initializing a base as in QObject(aParent) is similar to initializing a member, but bases are always initialized first. Therefore, it would be clearer to list QObject before the members, so the list of initializers is in chronological order.
The order of initialization always follows the order the bases are named after class and the order the members are declared, no matter how the initializer sequence is written.
A class instance that is a base of a derived class is sometimes called a "base class subobject", so in some sense a base class is a distinct 'part' of your derived class.
In your constructor's initializer list, the QObject(aParent) is choosing how the base class is constructed. In this case a single parameter constructor is being used. If the base class were omitted from the initializer list of your derived class' constructor its default constructor would be used.
It's not strictly a member variable, although like a member variable it's a constituent part of your derived class along with any other base class subobjects and other members.
Not quite. It tells the base class's constructor what to do. Imagine this class:
class A
{
public:
A(int val)
: value(val)
{
}
protected:
int value;
};
To construct A, you have to pass an int. This is always true, even if you derive from it.
Say you are class B, which derives from A. You are an A, but you still have to tell the A part of your class how to construct itself:
class B : public A
{
public:
B()
: A(5)
{
}
int GetValue()
{
return value;
}
};
The members of A become your members, though, because you are an A.
In machine memory, the scenario is kind of how you described, but only in simple cases. It becomes more complicated with virtual functions, multiple inheritance, and virtual inheritance. If you stick to the is-a and has-a relationships, then you may avoid some headaches :)