Factory method anti-if implementation - c++

I'm applying the Factory design pattern in my C++ project, and below you can see how I am doing it. I try to improve my code by following the "anti-if" campaign, thus want to remove the if statements that I am having. Any idea how can I do it?
typedef std::map<std::string, Chip*> ChipList;
Chip* ChipFactory::createChip(const std::string& type) {
MCList::iterator existing = Chips.find(type);
if (existing != Chips.end()) {
return (existing->second);
}
if (type == "R500") {
return Chips[type] = new ChipR500();
}
if (type == "PIC32F42") {
return Chips[type] = new ChipPIC32F42();
}
if (type == "34HC22") {
return Chips[type] = new Chip34HC22();
}
return 0;
}
I would imagine creating a map, with string as the key, and the constructor (or something to create the object). After that, I can just get the constructor from the map using the type (type are strings) and create my object without any if. (I know I'm being a bit paranoid, but I want to know if it can be done or not.)

You are right, you should use a map from key to creation-function.
In your case it would be
typedef Chip* tCreationFunc();
std::map<std::string, tCreationFunc*> microcontrollers;
for each new chip-drived class ChipXXX add a static function:
static Chip* CreateInstance()
{
return new ChipXXX();
}
and also register this function into the map.
Your factory function should be somethink like this:
Chip* ChipFactory::createChip(std::string& type)
{
ChipList::iterator existing = microcontrollers.find(type);
if (existing != microcontrollers.end())
return existing->second();
return NULL;
}
Note that copy constructor is not needed, as in your example.

The point of the factory is not to get rid of the ifs, but to put them in a separate place of your real business logic code and not to pollute it. It is just a separation of concerns.

If you're desperate, you could write a jump table/clone() combo that would do this job with no if statements.
class Factory {
struct ChipFunctorBase {
virtual Chip* Create();
};
template<typename T> struct CreateChipFunctor : ChipFunctorBase {
Chip* Create() { return new T; }
};
std::unordered_map<std::string, std::unique_ptr<ChipFunctorBase>> jumptable;
Factory() {
jumptable["R500"] = new CreateChipFunctor<ChipR500>();
jumptable["PIC32F42"] = new CreateChipFunctor<ChipPIC32F42>();
jumptable["34HC22"] = new CreateChipFunctor<Chip34HC22>();
}
Chip* CreateNewChip(const std::string& type) {
if(jumptable[type].get())
return jumptable[type]->Create();
else
return null;
}
};
However, this kind of approach only becomes valuable when you have large numbers of different Chip types. For just a few, it's more useful just to write a couple of ifs.
Quick note: I've used std::unordered_map and std::unique_ptr, which may not be part of your STL, depending on how new your compiler is. Replace with std::map/boost::unordered_map, and std::/boost::shared_ptr.

No you cannot get rid of the ifs. the createChip method creats a new instance depending on constant (type name )you pass as argument.
but you may optimaze yuor code a little removing those 2 line out of if statment.
microcontrollers[type] = newController;
return microcontrollers[type];

To answer your question: Yes, you should make a factory with a map to functions that construct the objects you want. The objects constructed should supply and register that function with the factory themselves.
There is some reading on the subject in several other SO questions as well, so I'll let you read that instead of explaining it all here.
Generic factory in C++
Is there a way to instantiate objects from a string holding their class name?

You can have ifs in a factory - just don't have them littered throughout your code.

struct Chip{
};
struct ChipR500 : Chip{};
struct PIC32F42 : Chip{};
struct ChipCreator{
virtual Chip *make() = 0;
};
struct ChipR500Creator : ChipCreator{
Chip *make(){return new ChipR500();}
};
struct PIC32F42Creator : ChipCreator{
Chip *make(){return new PIC32F42();}
};
int main(){
ChipR500Creator m; // client code knows only the factory method interface, not the actuall concrete products
Chip *p = m.make();
}

What you are asking for, essentially, is called Virtual Construction, ie the ability the build an object whose type is only known at runtime.
Of course C++ doesn't allow constructors to be virtual, so this requires a bit of trickery. The common OO-approach is to use the Prototype pattern:
class Chip
{
public:
virtual Chip* clone() const = 0;
};
class ChipA: public Chip
{
public:
virtual ChipA* clone() const { return new ChipA(*this); }
};
And then instantiate a map of these prototypes and use it to build your objects (std::map<std::string,Chip*>). Typically, the map is instantiated as a singleton.
The other approach, as has been illustrated so far, is similar and consists in registering directly methods rather than an object. It might or might not be your personal preference, but it's generally slightly faster (not much, you just avoid a virtual dispatch) and the memory is easier to handle (you don't have to do delete on pointers to functions).
What you should pay attention however is the memory management aspect. You don't want to go leaking so make sure to use RAII idioms.

Related

Why do they say that in the Proto-type Pattern - be used to simply duplicate the original object whenever a new one is needed?

I am trying to learn the design pattern. I am a C++ programmer. Currently, I am juggling with the Proto-type pattern. I could co-relate Prototype with the factory type. However, there are a lot of differences between factory and prototype pattern. For example, in the prototype pattern each derived class registers its prototype with the base/super class.
However, looking at the wikipedia article - I couldn't understood the following points.
Rather than retrieving the data and re-parsing it each time a new object is created, the prototype pattern can be used to simply duplicate the original object whenever a new one is needed.
avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.
Here is the program, I created to demonstrate the prototype pattern in C++. However, I cannot find any benefit out of it. How come a prototype pattern will help in quickly creating the object here. I can see that the object has to call 'new' every time. Here is the entire program, please correct me if you think that I haven't implemented the prototype pattern correctly.
Sorry for the long program - but trust me it is quite simple.
Like a factory object - here is the prototype class
-- basically an abstract.
class Itransport
{
public:
enum transportPacketType
{
udp,
tcp,
MAX
};
private:
static std::list<Itransport *> prototypesList;
protected:
virtual Itransport::transportPacketType getPacketType() = 0;
virtual Itransport* clone() = 0;
/** This will be called by the derived classes **/
static void registertoPrototypeList(Itransport *packet)
{
prototypesList.push_back(packet);
}
public:
virtual void showMessage() = 0;
static Itransport* makeClone(Itransport::transportPacketType packType)
{
std::list<Itransport *>::iterator it;
for(it = prototypesList.begin(); it != prototypesList.end(); it++)
{
if( (*it)->getPacketType() == packType )
{
return (*it)->clone();
}
}
}
virtual ~Itransport() = 0;
};
Itransport::~Itransport()
{
std::cout<<"Itransport Destructor called"<<std::endl;
}
std::list<Itransport *> Itransport::prototypesList;
Here is the concrete type of the Itransport Packet -
class udpPacket: public Itransport
{
private:
static udpPacket udpTransportPacket;
protected:
Itransport::transportPacketType getPacketType()
{
return Itransport::udp;
}
Itransport* clone()
{
return new udpPacket();
}
public:
void showMessage()
{
std::cout<<"This is a UDP Packet"<<std::endl;
}
udpPacket()
{
std::cout<<"UDP Packet Constructed"<<std::endl;
registertoPrototypeList(this);
}
~udpPacket()
{
std::cout<<"Destructor of udp called"<<std::endl;
}
};
static udpPacket udpTransportPacket;
Here is the client -
int main()
{
Itransport *udpPacket;
Itransport *udpPacket2;
udpPacket = Itransport::makeClone(Itransport::udp);
udpPacket->showMessage();
udpPacket2 = Itransport::makeClone(Itransport::udp);
udpPacket2->showMessage();
delete udpPacket;
delete udpPacket2;
return 0;
}
I couldn't find any benefits related to 'new' here. Please throw some light on it.
I can have a go at explaining the first point:
Rather than retrieving the data and re-parsing it each time a new
object is created, the prototype pattern can be used to simply
duplicate the original object whenever a new one is needed.
Imagine a computer game that has to create a lot of monsters. Say all the different types of monster are not known at compile time but you construct a monster of a particular type from some input data that provides information about what color the monster is, etc:
class Monster {
public:
Monster(InputDataHandle handle) {
// Retrieve input data...
// Parse input data...
}
void setPosition(Position);
};
Then every time you want to construct, say a red monster you have to retrieve the data and re-parse:
// Spawn a lot of red monsters
for (int i = 0; i != large_number; ++i) {
auto red = new Monster(red_monster_data); // Must retrieve data and re-parse!
red->setPosition(getRandomPosition());
game.add(red);
}
Clearly that is inefficient. One way of solving it is using the Prototype Pattern. You create one "prototype" red monster and every time you want to create an instance of a red monster you simply copy the prototype and you don't have to retrieve and re-parse the input data:
auto prototype_red_monster = new Monster(red_monster_data);
for (int i = 0; i != large_number; ++i) {
auto red = prototype_red_monster->clone();
red->setPosition(getRandomPosition());
game.add(red);
}
But how is the clone function implemented? This brings us to the second point which I don't really understand:
avoid the inherent cost of creating a new object in the standard way
(e.g., using the 'new' keyword) when it is prohibitively expensive for
a given application.
The clone function fundamentally has to allocate memory for the new object and copy data in from itself. I'm not sure I know what they are referring to when they talk about the "inherent cost of the new keyword". The examples are in Java and C# which have clone() and MemberwiseClone() respectively. In those languages you don't need to call new. I don't know how clone() and MemberwiseClone() are implemented but I don't see how they can "avoid the inherent cost of the new keyword".
In C++ we have to implement clone() ourselves and it will typically use new and use the copy constructor:
Monster* clone() {
return new Monster(*this);
}
In this case the copy constructor is much cheaper than creating the object from scratch. In your case it might not be.
The fact you cannot find any benefit from the Prototype Pattern in your case might mean it is the wrong pattern for your case and you will be better off with a different pattern like the Object Pool, Flyweight or Abstract Factory Pattern.

Accessing derived members from a container of base pointers

Consider the following code:
struct Object
{
bool hasComponent(std::string sComponentID);
Component& getComponent(std::string sComponentID);
std::vector<Component*> vComponents;
}
struct System
{
std::vector<Object*> vObjects;
}
My system will iterate over each Object in its vector and need to access data from derived members of Component (they all contain different state and data for the system to use).
I've considered something like this:
struct NetworkComponent : Component
{
std::string sID;
NetworkComponent(std::string tempID) : sID(tempID) {};
//Network data here
}
for(Object* p : vObjects)
{
if(p->hasComponent("network")
{
NetworkComponent& network = static_cast<NetworkComponent&>(p->getComponent("network");
//Access the data in the structure and do stuff with it.
}
}
This does however feel VERY "hacky"; not to mention unsafe.
I was wondering if there is a better way to do things like this, or at the very least how to avoid this problem in the future?
Are there any good articles written on this subject that I can look up?
EDIT: dynamic_cast is NOT an option due to how slow it is.
It sounds like you are trying to reinvent dynamic_cast
I'd refactor the getComponent method to return a pointer (a nullptr if no such component exists) instead of a reference and also pass the string argument with a constant reference:
Component * getComponent(const std::string & sComponentId);
Then you can do something like this:
template <typename CompType, typename ... Args>
CompType * getComponentOfType(Args && ... args)
{ return dynamic_cast<CompType *>(getComponent(std::forward<Args>(args)...)); }
If dynamic_cast is not an option here, use static_cast. By doing this you only lose a layer of safety for programming errors in this case.
And do something like:
for(Object * const p : vObjects) {
assert(p);
NetworkComponent * const net =
p->getComponentOfType<NetworkComponent>("network");
if (net) {
// Use the network component.
}
}
You can define class Object to contain virtual methods, which you want to have in derived classes.
Each of them should throw an exception, which mean this object didn't redefined this method.
Of course, in each of derived classes you should redefine methods that it's objects should have.

What is the proper way to handle a large number of interface implementations?

For one of my current projects I have an interface defined for which I have a large number of implementations. You could think of it as a plugin interface with many plugins.
These "plugins" each handle a different message type in a network protocol.
So when I get a new message, I loop through a list of my plugins, see who can handle it, and call into them via the interface.
The issue I am struggling with is how to allocate, initialize, and "load" all the implementations into my array/vector/whatever.
Currently I am declaring all of the "plugins" in main(), then calling an "plugin_manager.add_plugin(&plugin);" for each one. This seems less than ideal.
So, the actual questions:
1. Is there a standardized approach to this sort of thing?
2. Is there any way to define an array (global?) pre-loaded with the plugins?
3. Am I going about this the wrong way entirely? Are there other (better?) architecture options for this sort of problem?
Thanks.
EDIT:
This compiles (please excuse the ugly code)... but it kind of seems like a hack.
On the other hand, it solves the issue of allocation, and cleans up main()... Is this a valid solution?
class intf
{
public:
virtual void t() = 0;
};
class test : public intf
{
public:
test(){}
static test* inst(){ if(!_inst) _inst = new test; return _inst; }
static test* _inst;
void t(){}
};
test* test::_inst = NULL;
intf* ints[] =
{
test::inst(),
NULL
};
Store some form of smart pointer in a container. Dynamically allocate the plugins and register them in the container so that they can be used later.
One possible approach for your solution would be, if you have some form of message id that the plugin can decode, to use a map from that id to the plugin that handles that. This approach allows you to have fast lookup of the plugin given the input message.
One way of writing less code would be to use templates for the instantiation function. Then you only need to write one and put it in the interface, instead of having one function per implementation class.
class intf
{
public:
virtual void t() = 0;
template<class T>
static T* inst()
{
static T instance;
return &instance;
}
};
class test : public intf { ... };
intf* ints[] =
{
intf::inst<test>(),
NULL
};
The above code also works around two bugs you have in your code: One is a memory leak, in your old inst() function you allocate but you never free; The other is that the constructor sets the static member to NULL.
Other tips is to read more about the "singleton" pattern, which is what you have. It can be useful in some situations, but is generally advised against.

templated abstract factory class with pooling

I'm working on a game engine component that handles events. What I'm trying to do is create a system that I can register new event types by name. The event manager will then hold a collection of event types and the factories to generate such an event type BUT the twist is that I want to make it used a pooling system such that I create an event, use it and then rather than deleting it, throw it into a list. Next time I create that event, rather than using the heap, I can just allocate from the pool.
SO given these hierarchy of event types...
struct TEvent
{
int nID;
int nTimeStamp;
};
struct TCollisionEvent : public TEvent
{
TEntity* pEntity1;
TEntity* pEntity2;
Vector3* pvecPoint;
};
I then created a smart factory which does this creation/recyling operation:
template <class BASE_CLASS>
class CSmartFactory
{
private:
typedef typename std::list<BASE_CLASS*> TBaseList;
typedef typename std::list<BASE_CLASS*>::iterator TBaseListItr;
TBaseList* m_plstPool;
public:
explicit CSmartFactory()
{
m_plstPool = NULL;
}
~CSmartFactory()
{
TBaseListItr itr;
if (m_plstPool)
{
for (itr = m_plstPool->begin(); itr != m_plstPool->end(); itr++)
{
BASE_CLASS* pEntity = *itr;
SAFE_DELETE(pEntity);
}
m_plstPool->clear();
SAFE_DELETE(m_plstPool);
}
}
bool Init(int nPoolSize)
{
bool bReturn = false;
do
{
m_plstPool = new TBaseList;
IwAssert(MAIN, m_plstPool);
while (nPoolSize--)
{
BASE_CLASS* pBaseObject = new BASE_CLASS;
IwAssert(MAIN, pBaseObject);
m_plstPool->push_back(pBaseObject);
}
bReturn = true;
} while(0);
return bReturn;
}
BASE_CLASS* Create()
{
BASE_CLASS* pBaseObject = NULL;
//
// grab a pre-made entity from the pool or allocate a new one
if (m_plstPool->size() > 0)
{
pBaseObject = m_plstPool->front();
m_plstPool->pop_front();
pBaseObject->Clear();
}
else
{
pBaseObject = new BASE_CLASS;
IwAssert(MAIN, pBaseObject);
}
return pBaseObject;
}
void Recycle(BASE_CLASS* pBaseObject)
{
m_plstPool->push_back(pBaseObject);
}
};
SO now I can do this:
CSmartFactory<TCollisionEvent>* pCollisionEventFactory = new CSmartFactory<TCollisionEvent>;
BUT what I want to do is have my event manager allow for dynamic event registration but that's where I run into my snag.
Ideally RegisterEvent will track the name and factory pointer in an stl::map or something but not quite sure how to get to that point. Maybe I've gone down the wrong path altogether.
This compiles
class TEventManager
{
public:
TEventManager();
~TEventManager();
bool RegisterEvent(char* pszEventName, CSmartFactory<TEvent>* pFactory);
};
Until you add
TEventManager::RegisterEvent("CollisionEvent", new CSmartFactory<TEntityCollisionEvent>);
So now I'm hopelessly trying to find a way to make this all work.
Anybody got some ideas here!?
Fred
I assume that you want to reuse events to avoid expensive heap malloc/free's?
I think the right answer here is not to convolute your code by writing your own structure for reusing objects, but to use a small-object allocator. As a start, it may be worth looking into boost::pool.
The two classes CSmartFactory<TEntityCollisionEvent> and CSmartFactory<TEvent> will be generated to something like
CSmartFactory_TEntityCollisionEvent
CSmartFactory_TEvent
They are actually two separate and unrelated classes. Trying to use them interchangeably would be unwise, although they behave the same (their type classes are polymorphic right).
Dynamic casting wont work, you could however try to use brute force casting:
TEventManager::RegisterEvent("CollisionEvent",
reinterpret_cast<CSmartFactory<TEvent>*>(new CSmartFactory<TEntityCollisionEvent>));
Warning: At your own risk! ;-)
OK so after a lot of head banging, I realized the solution is FAR simpler than what I was trying to pull off.
All the manager should care about is managing a TEvent*. Each TEvent has a unique hash value that makes it unique so when a new event is added both the string name and hash name of that even is stored. So from there I can add a pointer to any subclass so long as it's casted to TEvent.
I was making it FAR more complex than it needed to be.

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