Answer: In short use virtual functions! So don't actually use this as good design, but for learning purposes take a read!
I want to start off by saying I am using c++ and Qt I have a vector of Shape pointers (Base class)
Edit: doSomething() is not a member of the Base class but instead a derived class member. Which is why I am using dynamic_cast to get Shape* to the Derived* so that I can access it. I am really doing this just out of curiosity at this point though and for other peoples learning about c++'s type system
#include <vector>
using namespace std;
vector<Shape *> vec;
Where I push back some derived classes of shape
vec.push_back(new Square());
vec.push_back(new Circle());
Ok then I get an iterator to the beginning
vector<Shape *>::iterator tmp = vec.begin();
Here I want to iterate through the vectors
for(;tmp != vec.end(); ++tmp)
{
if(typeid(**tmp).name() == typeid(Square).name())
{
Square * sptr = dynamic_cast<Square *>(*tmp);
sptr->doSomething();
}
else if(typeid(**tmp).name() == typeid(Circle).name())
{
Circle * cptr = dynamic_cast<Circle *>(*tmp);
cptr->doSomething();
}
}
However Both result in the Square output; not the circle for the second. I tried comparing the memory locations of typeid
Like so:
&typeid(**tmp) == &typeid(Square)
and the same for circle but tmp always results in the square for the case above and when ran against the circle right afterwards... Is dynamic cast doing something with the vector as a whole of am I just missing something with how typeid() works?
Edit: Here is the answer, thanks to user4581301 (I also added some thing too!):
#include <iostream>
#include <vector>
#include <typeinfo>
struct Shape
{
virtual ~Shape(){} //Something here must be virtual or pure virtual!
};
struct Circle: Shape
{
void doSomething(){std::cout << "Circle" << std::endl;}
};
struct Square: Shape
{
void doSomething(){std::cout << "Square" << std::endl;}
};
int main()
{
std::vector<Shape *> vec;
vec.push_back(new Square());
vec.push_back(new Circle());
std::vector<Shape *>::iterator tmp = vec.begin();
for(;tmp != vec.end(); ++tmp)
{
if(&typeid(**tmp) == &typeid(Square))
{
Square * sptr = dynamic_cast<Square *>(*tmp);
sptr->doSomething();
}
else if(&typeid(**tmp) == &typeid(Circle))
{
Circle * cptr = dynamic_cast<Circle *>(*tmp);
cptr->doSomething();
}
}
}
doSomething
is avirtual
member function ofShape
, you can calldoSomething
without doing any gymnastics to determine the type. IfdoSomething
is not avirtual
member function ofShape
, ask yourself "Why isn't it?" – user4581301doSomething
asvirtual
function. Check this out.coliru.stacked-crooked.com/a/365df4bc103ee929. If it is notvirtual
, then the compilation itself will fail. – P.W#include <bits/stdc++.h>
isn't something we should be passing on. Plus using it means you don't need to include any of the other things you've included. – user4581301Circle
andSquare
are proper polymorphic inheritors ofShape
: ideone.com/LU6mJo But without at least onevirtual
function in the base... It just won't work: ideone.com/mUYC84 – user4581301