I have shared pointers of Child objects stored in a Vector of Base shared pointers and I need to dynamically cast the elements of the Base vector to its Child type, such that I can invoke function with Child specific signature.
An example follows below. The first code block defines the class hierarchy and the "identify" functions that I would like to use. The second code block gives a specific example of how I want to invoke a TYPE-specific "identify" function, given that I can cast the original object type from the Base class to a Child class (e.g. A,B,C).
Is there any pattern or technique that I can tackle this issue?
#include <iostream>
#include <memory>
#include <vector>
class Base {};
class A : public Base{};
class B : public Base{};
class C : public Base{};
class CollectionOfBase
{
public:
void add (std::shared_ptr<Base> item){m_items.push_back(item);}
std::vector<std::shared_ptr<Base>> const& getItems() const {return m_items;}
private:
std::vector<std::shared_ptr<Base>> m_items;
};
// I want to use these 3 functions instead of identify( std::shared_ptr<Base> const& )
void identify( std::shared_ptr<A> const& )
{
std::cout << "A" << std::endl;
}
void identify( std::shared_ptr<B> const& )
{
std::cout << "B" << std::endl;
}
void identify( std::shared_ptr<C> const& )
{
std::cout << "C" << std::endl;
}
//This function works in the below for loop, but this is not what I need to use
void identify( std::shared_ptr<Base> const& )
{
std::cout << "Base" << std::endl;
}
Below, you can find the second code block:
int main()
{
using namespace std;
CollectionOfBase collection;
collection.add(make_shared<A>());
collection.add(make_shared<A>());
collection.add(make_shared<C>());
collection.add(make_shared<B>());
for (auto const& x : collection.getItems())
{
// THE QUESTION:
// How to distinguish different type of items
// to invoke "identify" with object specific signatures (e.g. A,B,C) ???
// Can I cast somehow the object types that I push_back on my Collection ???
// Note that this loop does not know the add order AACB that we pushed the Child pointers.
identify(x);
}
/*
The desired output of this loop should be:
A
A
C
B
*/
return 0;
}
The code is also available on Ideone.