How to create a collection of heterogeneous objects - c++

I would like to create a collection of heterogeneous objects; ie. objects of different types.
This would be useful when these objects have similar functionality (including members), but don't derive from the same parent class.
A perfect example of this are random number engines: minstd_rand, mt19937 and ranlux24 are all engines. They have the same members (such as the call operator ()), but don't derive from a common "Engine" class and so are of different types.
The same is the case with random number distributions.
Had there been a common root class 'Engine', I could easily have created a vector of these objects as follows:
vector<Engine> engines {minstd_rand, mt19937, ranlux24};
Having done this, I could then invoke a function in a loop, as follows:
/// Generate 10 random numbers.
void gen(vector<Engine>& engines)
{
for (auto& e : engines)
for (int i = 0; i < 10; i++)
cout << e() << endl;
}
int main()
{
gen(engines); /// Invocation
}
However, I can't do this.
If I use a tuple to wrap each engine, each object would have a different type:
tuple<type1>, tuple<type2>, ....
Again, the types would be heterogeneous and I couldn't create a collection of them.
So the question is, is it possible to create a collection of heterogeneous objects and if so, how?

You can use vector<function<size_t ()>> to hold these engines.
using Engine = function<size_t ()>;
vector<Engine> engines = {minstd_rand{}, mt19937{}, ranlux24{}};
for (auto &e : engines) {
cout << e() << endl;
}

You can simply create your own polymorphic hierarchy to wrap your different separately typed pseudo random number generators in. This is made easier by the fact that the different standard generators have a common interface even though they do not derive from a common base type.
Something a bit like this:
// Base interface class
class prng
{
public:
using dist_type = std::uniform_int_distribution<int>;
virtual ~prng() = default;
virtual int operator()(int min, int max) = 0;
protected:
dist_type dist;
template<typename PRNG>
static PRNG& eng()
{
thread_local static PRNG eng{std::random_device{}()};
return eng;
}
};
// smart pointers because polymorphism
using prng_uptr = std::unique_ptr<prng>;
// Generic class takes advantage of the different PRNG's
// similar interfaces
template<typename PRNG>
class typed_prng
: public prng
{
public:
int operator()(int min, int max) override
{ return dist(eng<PRNG>(), dist_type::param_type(min, max)); }
};
// Some nice names
using prng_minstd_rand = typed_prng<std::minstd_rand>;
using prng_mt19937 = typed_prng<std::mt19937>;
using prng_ranlux24 = typed_prng<std::ranlux24>;
int main()
{
// A vector of smart base pointers to typed instances
std::vector<prng_uptr> prngs;
// Add whatever generators you want
prngs.push_back(std::make_unique<prng_minstd_rand>());
prngs.push_back(std::make_unique<prng_mt19937>());
prngs.push_back(std::make_unique<prng_ranlux24>());
// numbers between 10 and 50
for(auto const& prng: prngs)
std::cout << (*prng)(10, 50) << '\n';
}

[ver 1] #Galik's post effectively demonstrated the basic technique of creating a polymorphic hierarchy, which I explain below.
The post was intended as a demonstration (rather than an implementation) of the technique involved. As such, it doesn't compile:
http://coliru.stacked-crooked.com/a/0465c2a11d3a0558
I have corrected the underlying issues and the following version works [ver 2]:
http://coliru.stacked-crooked.com/a/9bb0f47251e6dfed
The technique involved is important. I have voted for #Galik's post.
However, there was 1 issue with #Galik's solution: The random_device() engine was hard-coded in the base class itself. As such, it was always used, regardless of which engine was passed as argument in the sub-class. In fact, the engine passed as argument to the sub-class should have been used as the source of random numbers.
I have corrected this and also changed some of the names in the following version [ver 3]:
http://coliru.stacked-crooked.com/a/350eadb55a4bafe7
#include <vector>
#include <memory> /// unique_ptr
#include <random>
#include <iostream>
/// Declarations ...
class RndBase; /// Random number base class
/// Generic Random number sub-class
/// takes advantage of the different Engines' similar interfaces
template<typename Eng>
class RndSub;
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args);
/// Implementation ...
/// Random number base class
class RndBase
{
public:
using dist_type = std::uniform_int_distribution<int>;
virtual ~RndBase() = default;
virtual int operator() (int min, int max) = 0;
protected:
dist_type dist;
/// factory method
template<typename Eng>
static Eng& eng()
{
static Eng eng {Eng {}};
return eng;
}
}; // RndBase
/// Generic Random number sub-class
/// takes advantage of the different Engines' similar interfaces
template<typename Eng>
class RndSub : public RndBase
{
public:
/// Generate a random number.
int operator() (int min, int max) override
{
return dist(eng<Eng>(), dist_type::param_type(min, max));
}
};
int main()
{
using Eminstd_rand = RndSub<std::minstd_rand>;
using Emt19937 = RndSub<std::mt19937>;
using Eranlux24 = RndSub<std::ranlux24>;
/// smart pointers because of polymorphism
using pRndBase = std::unique_ptr<RndBase>;
/// A vector of smart base pointers to typed sub-classes
std::vector<pRndBase> prndbases;
/// Add whatever generators you want
prndbases.push_back(make_unique<Eminstd_rand> ());
prndbases.push_back(make_unique<Emt19937> ());
prndbases.push_back(make_unique<Eranlux24> ());
/// random numbers between 10 and 50
for(auto const& prb : prndbases)
std::cout << (*prb) (10, 50) << std::endl;
}
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T> {new T {args...}};
} // make_unique()
The explanation of the "Polymorphic Hierarchy" pattern is as follows:
1) We know all the engines have different types, though the same interface.
2) We create an abstract base class (RndBase), which includes this interface. It also defines a parameterized (static) factory method named eng() that creates an object of the parameter Eng and returns a reference to it. It is expected that an engine would be used as the parameter.
3) We create a parameterized sub-class named RndSub that derives from the base class RndBase. This class defines a call operator which returns the random number obtained by invoking the distribution.
4) Effectively, what we have done is as follows:
a) The heterogeneous engines are abstracted by the parameterized sub-class RndSub. Each sub-class is different.
b) However, they now have a single common base-class RndBase.
c) Since there is only a single base class (RndBase), we can now create a vector<RndBase>, which is homogeneous. The sub-classes of RndBase are heterogeneous.
d) Since the interface is common, we can use the interface defined in the base class to invoke the implementation in the sub-class. This implementation invokes the factory method eng() in the base class to obtain an engine, which is passed as argument to the distribution. This returns the random number.
This solution is specifically for Random numbers. I am trying to make a solution for any classes (that have a similar interface).

Related

Factory class driven by a map for determining the object type

I'm having a brain freeze and can't figure out how to best solve this issue. I'm creating objects from my factory class by calling
CreateEnvironment<T>(ARGS);
Now lets say that i want to save alot of class-types into a map and iterate through the map and call the method at runtime like this:
ITERATION:
CrateEnvironment<(*it)>(world);
(*it) should be the class type, which could be FOO or BAR for example. How do i achieve this instead of having alot of if statements?
Best regards
For each class you could have a function that would serve as generator and create a new object and return a pointer to it (or better, a shared_ptr).
In your container you could then store a the generator function pointers.
Step by step explanations:
Suppose you have these classes to populate your world:
struct GO { virtual void say_hello()=0; }; // Game Object
struct A:GO { void say_hello() { cout<<"I'm a werewolf\n";} };
struct B:GO { void say_hello() { cout<<"I'm a soldier\n";}};
You can then define a generic GO generator:
template <class T>
shared_ptr<GO> generator() {
return make_shared<T>();
};
This would serve as subsititue for your "type" container (for the simplicity of the example I've used a vector, but you could easily opt for a map):
typedef shared_ptr<GO> (*gen_fn)();
vector <gen_fn> generators{generator<A>, generator<B>};
You could then populate your universe like this, without any if:
vector<shared_ptr<GO>> universe;
default_random_engine generator;
uniform_int_distribution<int> distribution(0,generators.size()-1);
for (int i=0; i<10; i++) {
int mytype = distribution(generator);
universe.push_back(generators[mytype]());
}
for (auto x: universe)
x->say_hello();
And here an online demo.
Statistical remark: As the distribution is uniform, you will have a high probability of having the roughly the same proportion of each type of object. If you'd like to have different distribution, you could add several times generators of the same type. For example, with generators{generator<A>, generator<B>, generator<B>}; you'd have around 66% of soldiers and 33% of werewolves.

Object oriented design for hotel reservation system

I am practicing object oriented design for an upcoming interview. My question is about the design for a hotel reservation system:
- The system should be able to return an open room of a specific type or return all the open rooms in the hotel.
- There are many types of rooms in hotel like regular, luxury, celebrity and so on.
So far I have come up with following classes:
Class Room{
//Information about room
virtual string getSpecifications(Room *room){};
}
Class regularRoom: public Room{
//get specifications for regular room
}
Class luxuryRoom: public Room{
//get specifications for regular room
}
//Similarly create as many specialized rooms as you want
Class hotel{
vector<Room *>openRooms; //These are all the open rooms (type casted to Room type pointer)
Public:
Room search(Room *aRoom){ //Search room of a specific type
for(int i=0;i<openRooms.size();i++){
if(typeid(*aRoom)==typeid(*openRooms[i])) return *openRooms[i];
}
}
vector<Room> allOpenRooms(){//Return all open rooms
...
}
}
I am confused about the implementation of hotel.search() method where I am checking the type (which I believe should be handled by polymorphism in some way). Is there a better way of designing this system so that the search and allOpenRooms methods can be implemented without explicitly checking the type of the objects?
Going through the sub-class objects asking what type they are isn't really a good illustration of o-o design. You really need something you want to do to all rooms without being aware of what type each one is. For example print out the daily room menu for the room (which might be different for different types).
Deliberately looking for the sub-class object's type, while not being wrong, is not great o-o style. If you just want to do that, as the other respondents have said, just have "rooms" with a set of properties.
You could always let a room carry it's real type, instead of comparing the object type:
enum RoomType
{
RegularRoom,
luxuryRoom
};
class Room{
public:
explicit Room(RoomType room_type) : room_type_(room_type) { }
virtual ~Room(){}
RoomType getRoomType() const { return room_type_; }
private:
RoomType room_type_; // carries room type
};
class regularRoom: public Room{
public:
regularRoom() : Room(RegularRoom){ }
};
Room search(Room *aRoom)
{
//Search room of a specific type
for(size_t i=0;i<openRooms.size();i++)
{
if (aRoom->getRoomType() == RegularRoom) // <<-- compare room type
{
// do something
}
}
};
Do the different types of rooms have different behavior? From
the description you give, this is not a case where inheritance
should be used. Each room simply has an attribute, type, which
is, in its simplest form, simply an enum.
The simplest way is to have a Room type enumeration as #billz suggest you. The problem with tis way is that you must not forget to add a value to the enumeration and use it once every time you add a new type of Room to the system. You have to be sure you use the enum values only once, one time per class.
But, on the other hand, inheritance bassed dessigns only have sense if the types of the hierarchy shares a common behaviour. In other words, you want to use them in the same way, regardless of its type. IMPO, an OO/inheritance dessign is not the better way to do this.
The freak and scalable way I do this type of things is through typelists.
Normally, you have different search criteria for every type in your system. And, in many cases, the results of this search are not the same for different types of your system (Is not the ssame to search a luxury room and to search a normal room, you could have different search criteria and/or want different search results data).
For this prupose, the system has three typelists: One containing the data types, one containing the search criteria types, and one containing the search results types:
using system_data_types = type_list<NormalRoom,LuxuryRoom>;
using search_criteria_types = type_list<NormalRoomsCriteria,LuxuryRoommsCriteria>;
using search_results_types = type_list<NormalRoomSearchResults,LuxuryRoomSearchResults>;
Note that type_lists are sorted in the same manner. This is important, as I show below.
So the implementation of the search engine is:
class SearchEngine
{
private:
std::vector<VectorWrapper*> _data_lists; //A vector containing each system data type in its own vector. (One vector for NormalRoom, one for LuxuryRoom, etc)
//This function returns the vector that stores the system data type passed.
template<typename T>
std::vector<T>& _get_vector() {...} //Implementation explained below.
public:
SearchEngine() {...}//Explanation below.
~SearchEngine() {...}//Explanation below.
//This function adds an instance of a system data type to the "database".
template<typename T>
void addData(const T& data) { _get_vector<T>().push_back( data ); }
//The magic starts here:
template<typename SEARCH_CRITERIA_TYPE>//This template parameter is deduced by the compiler through the function parameter, so you can ommit it.
typename search_results_types::type_at<search_criteria_types::index_of<SEARCH_CRITERIA_TYPE>> //Return value (The search result that corresponds to the passed criteria. THIS IS THE REASON BECAUSE THE TYPELISTS MUST BE SORTED IN THE SAME ORDER.
search( const SEARCH_CRITERIA_TYPE& criteria)
{
using system_data_type = system_data_types::type_at<search_criteria_types::index_of<SEARCH_CRITERIA_TYPE>>; //The type of the data to be searched.
std::vector<system_data_type>& data = _get_vector<system_data_type>(); //A reference to the vector where that type of data is stored.
//blah, blah, blah (Search along the vector using the criteria parameter....)
}
};
And the search engine can be used as follows:
int main()
{
SearchEngine engine;
engine.addData(LuxuryRoom());
engine.addData(NormalRoom());
auto luxury_search_results = engine.search(LuxuryRoomCriteria()); //Search LuxuryRooms with the specific criteria and returns a LuxuryRoomSearchResults instance with the results of the search.
auto normal_search_results = engine.search(NormalRoomCriteria()); //Search NormalRooms with the specific criteria and returns a NormalRoomSearchResults instance with the results of the search.
}
The engine is based on store one vector for every system data type. And the engine uses a vector that stores that vectors.
We cannot have a polymorphic reference/pointer to vectors of different types, so we use a wrapper of a std::vector:
struct VectorWrapper
{
virtual ~VectorWrapper() = 0;
};
template<typename T>
struct GenericVectorWrapper : public VectorWrapper
{
std::vector<T> vector;
~GenericVectorWrapper() {};
};
//This template class "builds" the search engine set (vector) of system data types vectors:
template<int type_index>
struct VectorBuilder
{
static void append_data_type_vector(std::vector<VectorWrapper*>& data)
{
data.push_back( new GenericVectorWrapper< system_data_types::type_at<type_index> >() ); //Pushes back a vector that stores the indexth type of system data.
VectorBuilder<type_index+1>::append_data_type_vector(data); //Recursive call
}
};
//Base case (End of the list of system data types)
template<>
struct VectorBuilder<system_data_types::size>
{
static void append_data_type_vector(std::vector<VectorWrapper*>& data) {}
};
So the implementation of SearchEngine::_get_vector<T> is as follows:
template<typename T>
std::vector<T>& get_vector()
{
GenericVectorWrapper<T>* data; //Pointer to the corresponing vector
data = dynamic_cast<GenericVectorWrapper<T>*>(_data_lists[system_data_types::index_of<T>]); //We try a cast from pointer of wrapper-base-class to the expected type of vector wrapper
if( data )//If cast success, return a reference to the std::vector<T>
return data->vector;
else
throw; //Cast only fails if T is not a system data type. Note that if T is not a system data type, the cast result in a buffer overflow (index_of<T> returns -1)
}
The constructor of SearchEngine only uses VectorBuilder to build the list of vectors:
SearchEngine()
{
VectorBuilder<0>::append_data_type_vector(_data_list);
}
And the destructor only iterates over the list deleting the vectors:
~SearchEngine()
{
for(unsigned int i = 0 ; i < system_data_types::size ; ++i)
delete _data_list[i];
}
The advantages of this dessign are:
The search engine uses exactly the same interface for different searches (Searches with different system data types as target). And the process of "linking" a data type to its corresponding search criteria and results is done at compile-time.
That interface is type safe: A call to SearchEngine::search() returns a type of results based only on the search criteria passed. Assignament results errors are detected at compile-time. For example: NormalRoomResults = engine.search(LuxuryRoomCriteria()) generates a compilation error (engine.search<LuxuryRoomCriteria> returns LuxuryRoomResults).
The search engine is fully scalable: To add a new datatype to the system, you must only go to add the types to the typelists. The implementation of the search engine not changes.
Room Class
class Room{
public:
enum Type {
Regular,
Luxury,
Celebrity
};
Room(Type rt):roomType(rt), isOpen(true) { }
Type getRoomType() { return roomType; }
bool getRoomStatus() { return isOpen; }
void setRoomStatus(bool isOpen) { this->isOpen = isOpen; }
private:
Type roomType;
bool isOpen;
};
Hotel Class
class Hotel{
std::map<Room::Type, std::vector<Room*>> openRooms;
//std::map<Room::Type, std::vector<Room*>> reservedRooms;
public:
void addRooms(Room &room) { openRooms[room.getRoomType()].push_back(&room); }
auto getOpenRooms() {
std::vector<Room*> allOpenRooms;
for(auto rt : openRooms)
for(auto r : rt.second)
allOpenRooms.push_back(r);
return allOpenRooms;
}
auto getOpenRoomsOfType(Room::Type rt) {
std::vector<Room*> OpenRooms;
for(auto r : openRooms[rt])
OpenRooms.push_back(r);
return OpenRooms;
}
int totalOpenRooms() {
int roomCount=0;
for(auto rt : openRooms)
roomCount += rt.second.size();
return roomCount;
}
};
Client UseCase:
Hotel Marigold;
Room RegularRoom1(Room::Regular);
Room RegularRoom2(Room::Regular);
Room LuxuryRoom(Room::Luxury);
Marigold.addRooms(RegularRoom1);
Marigold.addRooms(RegularRoom2);
Marigold.addRooms(LuxuryRoom);
auto allRooms = Marigold.getOpenRooms();
auto LRooms = Marigold.getOpenRoomsOfType(Room::Luxury);
auto RRooms = Marigold.getOpenRoomsOfType(Room::Regular);
auto CRooms = Marigold.getOpenRoomsOfType(Room::Celebrity);
cout << " TotalOpenRooms : " << allRooms.size()
<< "\n Luxury : " << LRooms.size()
<< "\n Regular : " << RRooms.size()
<< "\n Celebrity : " << CRooms.size()
<< endl;
TotalOpenRooms : 4
Luxury : 2
Regular : 2
Celebrity : 0
If you really want to check that a room is of the same type as some other room, then typeid() is as good as any other method - and it's certainly "better" (from a performance perspective, at least) to calling a virtual method.
The other option is to not have separate classes at all, and store the roomtype as a member variable (and that is certainly how I would design it, but that's not a very good design for learning object orientation and inheritance - you don't get to inherit when the base class fulfils all your needs).

Dynamic binding in C++

I'm implementing a CORBA like server. Each class has remotely callable methods and a dispatch method with two possible input, a string identifying the method or an integer which would be the index of the method in a table. A mapping of the string to the corresponding integer would be implemented by a map.
The caller would send the string on the first call and get back the integer with the response so that it simply has to send the integer on subsequent calls. It is just a small optimization. The integer may be assigned dynamically on demand by the server object.
The server class may be derived from another class with overridden virtual methods.
What could be a simple and general way to define the method binding and the dispatch method ?
Edit: The methods have all the same signature (no overloading). The methods have no parameters and return a boolean. They may be static, virtual or not, overriding a base class method or not. The binding must correctly handle method overriding.
The string is class hierarchy bound. If we have A::foo() identified by the string "A.foo", and a class B inherits A and override the method A::foo(), it will still be identified as "A.foo", but the dispatcher will call A::foo if the server is an A object and B::foo if it is a B object.
Edit (6 apr): In other words, I need to implement my own virtual method table (vftable) with a dynamic dispatch method using a string key to identify the method to call. The vftable should be shared among objects of the same class and behave as expected for polymorphism (inherited method override).
Edit (28 apr): See my own answer below and the edit at the end.
Have you considered using a combination of boost::bind and boost::function? Between these two utilities you can easily wrap any C++ callable in a function object, easily store them in containers, and generally expect it all to "just work". As an example, the following code sample works exactly the way you would expect.
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct A { virtual void hello() { cout << "Hello from A!" << endl; } };
struct B : public A { virtual void hello() { cout << "Hello from B!" << endl; } };
int main( int argc, char * argv[] )
{
A a;
B b;
boost::function< void () > f1 = boost::bind( &A::hello, a );
boost::function< void () > f2 = boost::bind( &A::hello, b );
f1(); // prints: "Hello from A!"
f2(); // prints: "Hello from B!"
return 0;
}
It looks like you're looking for something like reflection or delegates -- I'm not 100% sure what you're trying to accomplish, but it seems the best way of doing that is just having a map of function pointers:
typedef size_t (*CommonMethodPointerType)(const unsigned char *);
std::map<std::string, CommonMethodPointerType> functionMapping;
size_t myFunc(const std::string& functionName, const unsigned char * argument) {
std::map<std::string, CommonMethodPointerType>::iterator functionPtrIterator
= functionMapping.find(functionName);
if (FunctionPtrIterator == functionMapping.end())
return ERROR_CODE;
return (*functionPtrIterator)(argument);
}
You could implement some form of optimization similar to your integer by returning the iterator to the client so long as you know the mapping will not change.
If you're looking for "dynamic binding" like that allowed in C# or dynamic languages like PHP, unfortunately you really can't do that -- C++ destroys type information when code is compiled.
Hope that helps!
You might like to rephrase the question slightly as static and dynamic binding actually have a specific meaning in C++.
For example, default values for parameters are determined at compile time so if I have a virtual method in a base class that declares default values for its parameters then those values are set at compile time.
Any new default values for these parameters that are declared in a derived class will be ignored at run time with the result being that the default parameter values in the base class will be used, even though you called the member function in the derived class.
The default parameter values are said to be statically bound.
Scott Meyers discusses this in an item in his excellent book "Effective C++".
HTH
Qt4 has a nice dynamic binding system that's made possible via their "Meta-Object Compiler" (moc). There's a nice writeup on it on their Qt Object Model page.
Here is a way do dynamically load classes from shared libraries on Linux http://www.linuxjournal.com/article/3687?page=0,0
There is also a stackoverflow question on this
C++ Dynamic Shared Library on Linux
The same can be done in Windows by dynamically loading C functions from DLLs and then loading those.
The map part is trivial after you have your dynamic loading solution
The really good book Advanced C++ programming idioms and idioms by James O. Coplien has a section on Incremental loading
Here is an example of my actual method. It Just Works (c) but I'm pretty sure a much cleaner and better way exist. It compiles and runs with g++ 4.4.2 as is. Removing the instruction in the constructor would be great, but I couldn't find a way to achieve this. The Dispatcher class is basically a dispatchable method table and each instance must have a pointer on its table.
Note: This code will implicitly make all dispatched methods virtual.
#include <iostream>
#include <map>
#include <stdexcept>
#include <cassert>
// Forward declaration
class Dispatchable;
//! Abstract base class for method dispatcher class
class DispatcherAbs
{
public:
//! Dispatch method with given name on object
virtual void dispatch( Dispatchable *obj, const char *methodName ) = 0;
virtual ~DispatcherAbs() {}
};
//! Base class of a class with dispatchable methods
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
// Requires a dispatcher singleton assigned in derived class constructor
assert( m_dispatcher != NULL );
m_dispatcher->dispatch( this, methodName );
}
protected:
DispatcherAbs *m_dispatcher; //!< Pointer on method dispatcher singleton
};
//! Class type specific method dispatcher
template <class T>
class Dispatcher : public DispatcherAbs
{
public:
//! Define a the dispatchable method type
typedef void (T::*Method)();
//! Get dispatcher singleton for class of type T
static Dispatcher *singleton()
{
static Dispatcher<T> vmtbl;
return &vmtbl;
}
//! Add a method binding
void add( const char* methodName, Method method )
{ m_map[methodName] = method; }
//! Dispatch method with given name on object
void dispatch( Dispatchable *obj, const char *methodName )
{
T* tObj = dynamic_cast<T*>(obj);
if( tObj == NULL )
throw std::runtime_error( "Dispatcher: class mismatch" );
typename MethodMap::const_iterator it = m_map.find( methodName );
if( it == m_map.end() )
throw std::runtime_error( "Dispatcher: unmatched method name" );
// call the bound method
(tObj->*it->second)();
}
protected:
//! Protected constructor for the singleton only
Dispatcher() { T::initDispatcher( this ); }
//! Define map of dispatchable method
typedef std::map<const char *, Method> MethodMap;
MethodMap m_map; //! Dispatch method map
};
//! Example class with dispatchable methods
class A : public Dispatchable
{
public:
//! Construct my class and set dispatcher
A() { m_dispatcher = Dispatcher<A>::singleton(); }
void method1() { std::cout << "A::method1()" << std::endl; }
virtual void method2() { std::cout << "A::method2()" << std::endl; }
virtual void method3() { std::cout << "A::method3()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
dispatcher->add( "method3", &T::method3 );
}
};
//! Example class with dispatchable methods
class B : public A
{
public:
//! Construct my class and set dispatcher
B() { m_dispatcher = Dispatcher<B>::singleton(); }
void method1() { std::cout << "B::method1()" << std::endl; }
virtual void method2() { std::cout << "B::method2()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
// call parent dispatcher initializer
A::initDispatcher( dispatcher );
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
}
};
int main( int , char *[] )
{
A *test1 = new A;
A *test2 = new B;
B *test3 = new B;
test1->dispatch( "method1" );
test1->dispatch( "method2" );
test1->dispatch( "method3" );
std::cout << std::endl;
test2->dispatch( "method1" );
test2->dispatch( "method2" );
test2->dispatch( "method3" );
std::cout << std::endl;
test3->dispatch( "method1" );
test3->dispatch( "method2" );
test3->dispatch( "method3" );
return 0;
}
Here is the program output
A::method1()
A::method2()
A::method3()
B::method1()
B::method2()
A::method3()
B::method1()
B::method2()
A::method3()
Edit (28 apr): The answers to this related question was enlightening. Using a virtual method with an internal static variable is preferable to using a member pointer variable that needs to be initialized in the constructor.
I've seen both your example and the answer to the other question. But if you talk about the m_dispatcher member, the situation is very different.
For the original question, there's no way to iterate over methods of a class. You might only remove the repetition in add("method", T::method) by using a macro:
#define ADD(methodname) add(#methodname, T::methodname)
where the '#' will turn methodname into a string like required (expand the macro as needed). In case of similarly named methods, this removes a source of potential typos, hence it is IMHO very desirable.
The only way to list method names IMHO is by parsing output of "nm" (on Linux, or even on Windows through binutils ports) on such files (you can ask it to demangle C++ symbols). If you want to support this, you may want initDispatcher to be defined in a separate source file to be auto-generated. There's no better way than this, and yes, it may be ugly or perfect depending on your constraints. Btw, it also allows to check that authors are not overloading methods. I don't know if it would be possible to filter public methods, however.
I'm answering about the line in the constructor of A and B. I think the problem can be solved with the curiously recurring template pattern, applied on Dispatchable:
template <typename T>
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
dispatcher()->dispatch( this, methodName );
}
protected:
static Dispatcher<T> dispatcher() {
return Dispatcher<T>::singleton();
//Or otherwise, for extra optimization, using a suggestion from:
//http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
static Dispatcher<T>& disp = Dispatcher<T>::singleton();
return disp;
}
};
Disclaimer: I couldn't test-compile this (I'm away from a compiler). You may need to forward-declare Dispatcher, but since it gets a template argument I guess argument-dependant lookup makes that unnecessary (I'm not enough of a C++ guru to be sure of this).
I've added a dispatcher() method for convenience, if it is needed elsewhere (otherwise you can inline it in dispatch()).
The reason CRTP is so simple here and so complicated in the other thread is that here your member was not static. I first thought of making it static, then I thought there was no reason for saving the result of the call to singleton() and waste memory, then I looked it up and found this solution. I'm dubious if the extra reference in dispatcher() does save any extra time.
In any case, if a m_dispatcher member was needed, it could be initialized in the Dispatchable() constructor.
About your example, since initDispatcher() is a template method, I frankly doubt it is necessary to readd method1 and method2. A::initDispatcher(Dispatcher<B> dispatcher) will correctly add B::method1 to dispatcher.
By the way - don't forget that the numeric position of virtual functions dispatched from a vtable correspond identically, with all compilers, to the sequence they appear in the corresponding header file. You may be able to take advantage of that. That is a core principle upon which Microsoft COM technology is based.
Also, you might consider an approach published in "Game Programming Gems" (first volume) by Mark DeLoura. The article is entitled a "generic function binding interface" and is intended for RPC / network binding of functions. It may be exactly what you want.
class Report //This denotes the base class of C++ virtual function
{
public:
virtual void create() //This denotes the C++ virtual function
{
cout <<"Member function of Base Class Report Accessed"<<endl;
}
};
class StudentReport: public Report
{
public:
void create()
{
cout<<"Virtual Member function of Derived class StudentReportAccessed"<<endl;
}
};
void main()
{
Report *a, *b;
a = new Report();
a->create();
b = new StudentReport();
b->create();
}

Storing a list of arbitrary objects in C++

In Java, you can have a List of Objects. You can add objects of multiple types, then retrieve them, check their type, and perform the appropriate action for that type.
For example: (apologies if the code isn't exactly correct, I'm going from memory)
List<Object> list = new LinkedList<Object>();
list.add("Hello World!");
list.add(7);
list.add(true);
for (object o : list)
{
if (o instanceof int)
; // Do stuff if it's an int
else if (o instanceof String)
; // Do stuff if it's a string
else if (o instanceof boolean)
; // Do stuff if it's a boolean
}
What's the best way to replicate this behavior in C++?
boost::variant is similar to dirkgently's suggestion of boost::any, but supports the Visitor pattern, meaning it's easier to add type-specific code later. Also, it allocates values on the stack rather than using dynamic allocation, leading to slightly more efficient code.
EDIT: As litb points out in the comments, using variant instead of any means you can only hold values from one of a prespecified list of types. This is often a strength, though it might be a weakness in the asker's case.
Here is an example (not using the Visitor pattern though):
#include <vector>
#include <string>
#include <boost/variant.hpp>
using namespace std;
using namespace boost;
...
vector<variant<int, string, bool> > v;
for (int i = 0; i < v.size(); ++i) {
if (int* pi = get<int>(v[i])) {
// Do stuff with *pi
} else if (string* si = get<string>(v[i])) {
// Do stuff with *si
} else if (bool* bi = get<bool>(v[i])) {
// Do stuff with *bi
}
}
(And yes, you should technically use vector<T>::size_type instead of int for i's type, and you should technically use vector<T>::iterator instead anyway, but I'm trying to keep it simple.)
Your example using Boost.Variant and a visitor:
#include <string>
#include <list>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
using namespace std;
using namespace boost;
typedef variant<string, int, bool> object;
struct vis : public static_visitor<>
{
void operator() (string s) const { /* do string stuff */ }
void operator() (int i) const { /* do int stuff */ }
void operator() (bool b) const { /* do bool stuff */ }
};
int main()
{
list<object> List;
List.push_back("Hello World!");
List.push_back(7);
List.push_back(true);
BOOST_FOREACH (object& o, List) {
apply_visitor(vis(), o);
}
return 0;
}
One good thing about using this technique is that if, later on, you add another type to the variant and you forget to modify a visitor to include that type, it will not compile. You have to support every possible case. Whereas, if you use a switch or cascading if statements, it's easy to forget to make the change everywhere and introduce a bug.
C++ does not support heterogenous containers.
If you are not going to use boost the hack is to create a dummy class and have all the different classes derive from this dummy class. Create a container of your choice to hold dummy class objects and you are ready to go.
class Dummy {
virtual void whoami() = 0;
};
class Lizard : public Dummy {
virtual void whoami() { std::cout << "I'm a lizard!\n"; }
};
class Transporter : public Dummy {
virtual void whoami() { std::cout << "I'm Jason Statham!\n"; }
};
int main() {
std::list<Dummy*> hateList;
hateList.insert(new Transporter());
hateList.insert(new Lizard());
std::for_each(hateList.begin(), hateList.end(),
std::mem_fun(&Dummy::whoami));
// yes, I'm leaking memory, but that's besides the point
}
If you are going to use boost you can try boost::any. Here is an example of using boost::any.
You may find this excellent article by two leading C++ experts of interest.
Now, boost::variant is another thing to look out for as j_random_hacker mentioned. So, here's a comparison to get a fair idea of what to use.
With a boost::variant the code above would look something like this:
class Lizard {
void whoami() { std::cout << "I'm a lizard!\n"; }
};
class Transporter {
void whoami() { std::cout << "I'm Jason Statham!\n"; }
};
int main() {
std::vector< boost::variant<Lizard, Transporter> > hateList;
hateList.push_back(Lizard());
hateList.push_back(Transporter());
std::for_each(hateList.begin(), hateList.end(), std::mem_fun(&Dummy::whoami));
}
How often is that sort of thing actually useful? I've been programming in C++ for quite a few years, on different projects, and have never actually wanted a heterogenous container. It may be common in Java for some reason (I have much less Java experience), but for any given use of it in a Java project there might be a way to do something different that will work better in C++.
C++ has a heavier emphasis on type safety than Java, and this is very type-unsafe.
That said, if the objects have nothing in common, why are you storing them together?
If they do have things in common, you can make a class for them to inherit from; alternately, use boost::any. If they inherit, have virtual functions to call, or use dynamic_cast<> if you really have to.
I'd just like to point out that using dynamic type casting in order to branch based on type often hints at flaws in the architecture. Most times you can achieve the same effect using virtual functions:
class MyData
{
public:
// base classes of polymorphic types should have a virtual destructor
virtual ~MyData() {}
// hand off to protected implementation in derived classes
void DoSomething() { this->OnDoSomething(); }
protected:
// abstract, force implementation in derived classes
virtual void OnDoSomething() = 0;
};
class MyIntData : public MyData
{
protected:
// do something to int data
virtual void OnDoSomething() { ... }
private:
int data;
};
class MyComplexData : public MyData
{
protected:
// do something to Complex data
virtual void OnDoSomething() { ... }
private:
Complex data;
};
void main()
{
// alloc data objects
MyData* myData[ 2 ] =
{
new MyIntData()
, new MyComplexData()
};
// process data objects
for ( int i = 0; i < 2; ++i ) // for each data object
{
myData[ i ]->DoSomething(); // no type cast needed
}
// delete data objects
delete myData[0];
delete myData[1];
};
Sadly there is no easy way of doing this in C++. You have to create a base class yourself and derive all other classes from this class. Create a vector of base class pointers and then use dynamic_cast (which comes with its own runtime overhead) to find the actual type.
Just for completeness of this topic I want to mention that you can actually do this with pure C by using void* and then casting it into whatever it has to be (ok, my example isn't pure C since it uses vectors but that saves me some code). This will work if you know what type your objects are, or if you store a field somewhere which remembers that. You most certainly DON'T want to do this but here is an example to show that it's possible:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a = 4;
string str = "hello";
vector<void*> list;
list.push_back( (void*) &a );
list.push_back( (void*) &str );
cout << * (int*) list[0] << "\t" << * (string*) list[1] << endl;
return 0;
}
While you cannot store primitive types in containers, you can create primitive type wrapper classes which will be similar to Java's autoboxed primitive types (in your example the primitive typed literals are actually being autoboxed); instances of which appear in C++ code (and can (almost) be used) just like primitive variables/data members.
See Object Wrappers for the Built-In Types from Data Structures and Algorithms with Object-Oriented Design Patterns in C++.
With the wrapped object you can use the c++ typeid() operator to compare the type.
I am pretty sure the following comparison will work:
if (typeid(o) == typeid(Int)) [where Int would be the wrapped class for the int primitive type, etc...]
(otherwise simply add a function to your primitive wrappers that returns a typeid and thus:
if (o.get_typeid() == typeid(Int)) ...
That being said, with respect to your example, this has code smell to me.
Unless this is the only place where you are checking the type of the object,
I would be inclined to use polymorphism (especially if you have other methods/functions specific with respect to type). In this case I would use the primitive wrappers adding an interfaced class declaring the deferred method (for doing 'do stuff') that would be implemented by each of your wrapped primitive classes. With this you would be able to use your container iterator and eliminate your if statement (again, if you only have this one comparison of type, setting up the deferred method using polymorphism just for this would be overkill).
I am a fairly inexperienced, but here's what I'd go with-
Create a base class for all classes you need to manipulate.
Write container class/ reuse container class.
(Revised after seeing other answers -My previous point was too cryptic.)
Write similar code.
I am sure a much better solution is possible. I am also sure a better explanation is possible. I've learnt that I have some bad C++ programming habits, so I've tried to convey my idea without getting into code.
I hope this helps.
Beside the fact, as most have pointed out, you can't do that, or more importantly, more than likely, you really don't want to.
Let's dismiss your example, and consider something closer to a real-life example. Specifically, some code I saw in a real open-source project. It attempted to emulate a cpu in a character array. Hence it would put into the array a one byte "op code", followed by 0, 1 or 2 bytes which could be a character, an integer, or a pointer to a string, based on the op code. To handle that, it involved a lot of bit-fiddling.
My simple solution: 4 separate stacks<>s: One for the "opcode" enum and one each for chars, ints and string. Take the next off the opcode stack, and the would take you which of the other three to get the operand.
There's a very good chance your actual problem can be handled in a similar way.
Well, you could create a base class and then create classes which inherit from it. Then, store them in a std::vector.
The short answer is... you can't.
The long answer is... you'd have to define your own new heirarchy of objects that all inherit from a base object. In Java all objects ultimately descend from "Object", which is what allows you to do this.
RTTI (Run time type info) in C++ has always been tough, especially cross-compiler.
You're best option is to use STL and define an interface in order to determine the object type:
public class IThing
{
virtual bool isA(const char* typeName);
}
void myFunc()
{
std::vector<IThing> things;
// ...
things.add(new FrogThing());
things.add(new LizardThing());
// ...
for (int i = 0; i < things.length(); i++)
{
IThing* pThing = things[i];
if (pThing->isA("lizard"))
{
// do this
}
// etc
}
}
Mike

How can I keep track of (enumerate) all classes that implement an interface

I have a situation where I have an interface that defines how a certain class behaves in order to fill a certain role in my program, but at this point in time I'm not 100% sure how many classes I will write to fill that role. However, at the same time, I know that I want the user to be able to select, from a GUI combo/list box, which concrete class implementing the interface that they want to use to fill a certain role. I want the GUI to be able to enumerate all available classes, but I would prefer not to have to go back and change old code whenever I decide to implement a new class to fill that role (which may be months from now)
Some things I've considered:
using an enumeration
Pros:
I know how to do it
Cons
I will have to update update the enumeration when I add a new class
ugly to iterate through
using some kind of static list object in the interface, and adding a new element from within the definition file of the implementing class
Pros:
Wont have to change old code
Cons:
Not even sure if this is possible
Not sure what kind of information to store so that a factory method can choose the proper constructor ( maybe a map between a string and a function pointer that returns a pointer to an object of the interface )
I'm guessing this is a problem (or similar to a problem) that more experienced programmers have probably come across before (and often), and there is probably a common solution to this kind of problem, which is almost certainly better than anything I'm capable of coming up with. So, how do I do it?
(P.S. I searched, but all I found was this, and it's not the same: How do I enumerate all items that implement a generic interface?. It appears he already knows how to solve the problem I'm trying to figure out.)
Edit: I renamed the title to "How can I keep track of... " rather than just "How can I enumerate..." because the original question sounded like I was more interested in examining the runtime environment, where as what I'm really interested in is compile-time book-keeping.
Create a singleton where you can register your classes with a pointer to a creator function.
In the cpp files of the concrete classes you register each class.
Something like this:
class Interface;
typedef boost::function<Interface* ()> Creator;
class InterfaceRegistration
{
typedef map<string, Creator> CreatorMap;
public:
InterfaceRegistration& instance() {
static InterfaceRegistration interfaceRegistration;
return interfaceRegistration;
}
bool registerInterface( const string& name, Creator creator )
{
return (m_interfaces[name] = creator);
}
list<string> names() const
{
list<string> nameList;
transform(
m_interfaces.begin(), m_interfaces.end(),
back_inserter(nameList)
select1st<CreatorMap>::value_type>() );
}
Interface* create(cosnt string& name ) const
{
const CreatorMap::const_iterator it
= m_interfaces.find(name);
if( it!=m_interfaces.end() && (*it) )
{
return (*it)();
}
// throw exception ...
return 0;
}
private:
CreatorMap m_interfaces;
};
// in your concrete classes cpp files
namespace {
bool registerClassX = InterfaceRegistration::instance("ClassX", boost::lambda::new_ptr<ClassX>() );
}
ClassX::ClassX() : Interface()
{
//....
}
// in your concrete class Y cpp files
namespace {
bool registerClassY = InterfaceRegistration::instance("ClassY", boost::lambda::new_ptr<ClassY>() );
}
ClassY::ClassY() : Interface()
{
//....
}
I vaguely remember doing something similar to this many years ago. Your option (2) is pretty much what I did. In that case it was a std::map of std::string to std::typeinfo. In each, .cpp file I registered the class like this:
static dummy = registerClass (typeid (MyNewClass));
registerClass takes a type_info object and simply returns true. You have to initialize a variable to ensure that registerClass is called during startup time. Simply calling registerClass in the global namespace is an error. And making dummy static allow you to reuse the name across compilation units without a name collision.
I referred to this article to implement a self-registering class factory similar to the one described in TimW's answer, but it has the nice trick of using a templated factory proxy class to handle the object registration. Well worth a look :)
Self-Registering Objects in C++ -> http://www.ddj.com/184410633
Edit
Here's the test app I did (tidied up a little ;):
object_factory.h
#include <string>
#include <vector>
// Forward declare the base object class
class Object;
// Interface that the factory uses to communicate with the object proxies
class IObjectProxy {
public:
virtual Object* CreateObject() = 0;
virtual std::string GetObjectInfo() = 0;
};
// Object factory, retrieves object info from the global proxy objects
class ObjectFactory {
public:
static ObjectFactory& Instance() {
static ObjectFactory instance;
return instance;
}
// proxies add themselves to the factory here
void AddObject(IObjectProxy* object) {
objects_.push_back(object);
}
size_t NumberOfObjects() {
return objects_.size();
}
Object* CreateObject(size_t index) {
return objects_[index]->CreateObject();
}
std::string GetObjectInfo(size_t index) {
return objects_[index]->GetObjectInfo();
}
private:
std::vector<IObjectProxy*> objects_;
};
// This is the factory proxy template class
template<typename T>
class ObjectProxy : public IObjectProxy {
public:
ObjectProxy() {
ObjectFactory::Instance().AddObject(this);
}
Object* CreateObject() {
return new T;
}
virtual std::string GetObjectInfo() {
return T::TalkToMe();
};
};
objects.h
#include <iostream>
#include "object_factory.h"
// Base object class
class Object {
public:
virtual ~Object() {}
};
class ClassA : public Object {
public:
ClassA() { std::cout << "ClassA Constructor" << std::endl; }
~ClassA() { std::cout << "ClassA Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassA"; }
};
class ClassB : public Object {
public:
ClassB() { std::cout << "ClassB Constructor" << std::endl; }
~ClassB() { std::cout << "ClassB Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassB"; }
};
objects.cpp
#include "objects.h"
// Objects get registered here
ObjectProxy<ClassA> gClassAProxy;
ObjectProxy<ClassB> gClassBProxy;
main.cpp
#include "objects.h"
int main (int argc, char * const argv[]) {
ObjectFactory& factory = ObjectFactory::Instance();
for (int i = 0; i < factory.NumberOfObjects(); ++i) {
std::cout << factory.GetObjectInfo(i) << std::endl;
Object* object = factory.CreateObject(i);
delete object;
}
return 0;
}
output:
This is ClassA
ClassA Constructor
ClassA Destructor
This is ClassB
ClassB Constructor
ClassB Destructor
If you're on Windows, and using C++/CLI, this becomes fairly easy. The .NET framework provides this capability via reflection, and it works very cleanly in managed code.
In native C++, this gets a little bit trickier, as there's no simple way to query the library or application for runtime information. There are many frameworks that provide this (just look for IoC, DI, or plugin frameworks), but the simplest means of doing it yourself is to have some form of configuration which a factory method can use to register themselves, and return an implementation of your specific base class. You'd just need to implement loading a DLL, and registering the factory method - once you have that, it's fairly easy.
Something you can consider is an object counter. This way you don't need to change every place you allocate but just implementation definition. It's an alternative to the factory solution. Consider pros/cons.
An elegant way to do that is to use the CRTP : Curiously recurring template pattern.
The main example is such a counter :)
This way you just have to add in your concrete class implementation :
class X; // your interface
class MyConcreteX : public counter<X>
{
// whatever
};
Of course, it is not applicable if you use external implementations you do not master.
EDIT:
To handle the exact problem you need to have a counter that count only the first instance.
my 2 cents
There is no way to query the subclasses of a class in (native) C++.
How do you create the instances? Consider using a Factory Method allowing you to iterate over all subclasses you are working with. When you create an instance like this, it won't be possible to forget adding a new subclass later.