Whenever you push an object of b
into vector vec
of Base
Objects, you create another object from temp
which is purely of type base
. You might be thinking (and you are not right!) that element which is being stored in vector
will be of type Base but it will be holding an object of type b
but it's not how you achieve Dynamic Polymorphism
in C++.
The statements:
std::vector<Base> vec; // 1
b temp; // 2
vec.push_back(temp); // 3
The third line will create a different object to type Base
by calling assignment operator of base class Base operator=(const Base& )
.
Also,b* temp = (b*)&vec[i];
is an undefined behavior because you are explicitly trying to cast a pointer to object of base
to it's derived class type b
but it doesn't hold object of type b
and hence, you may get unexpected behavior.
NOTE:
Use dynamic_cast for casting between base and derived class as it will make sure that the conversion is valid. Otherwise, it will return nullptr
. However, you need to make your base class polymorphic by having at least 1 virtual function.
If the cast is successful, dynamic_cast returns a value of type new-type. If the cast fails and new-type is a pointer type, it returns a null pointer of that type. If the cast fails and new-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
SOLUTION:
Use vector of pointers to base
class to achieve run-time polymorphism.
std::vector<base *> vec;
for (int i = 0; i < 5; i++) {
b *temp = new b();
vec.push_back(temp);
}
for (int i = 0; i < 5; i++) {
b* temp = dynamic_cast<b *>(vec[i]); // For dynamic cast, you need to add virtual functions to your base class
if (temp != nullptr)
std::cout << temp->d << std::endl;
}
EDIT:
Object Slicing is also a solution for your problem. Object Slicing
is the right keyword for this type of problems. Here is the definition of the Object Slicing
Object slicing happens when a derived class object is assigned to a base class object, additional attributes of a derived class object are sliced off to form the base class object.
I am quoting one of the answer in the link below. See this answer and answer for the best explanation and possible solution with some code snippet. See this article, it has explained the problem when pushing object of Derived class in a vector of base class.
"Slicing" is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is "sliced" away.
For example,
class A {
int foo;
};
class B : public A {
int bar;
};
So an object of type B has two data members, foo and bar.
Then if you were to write this:
B b;
A a = b;
Then the information in b about member bar is lost in a.