What's the point of IsA() in C++? - c++

I'm trying to figure out why some code bases use IsA() to determine object polymorphism if in C++ you can already safely upcast and down cast (using dynamic_cast) ?
So far the only case I see useful is when you are integrating a a scripting environment that is linked to the c++ codebase?
Thanks!

There are few reasons where and IsA() function, or even a dynamic_cast<>() are needed in C++. The worst examples of this type of code are the giant if-then statements using dynamic_casts, or switch statements on a type field. These represent a maintenance nightmare, where adding a class can involve updating dozens, or hundreds of different locations to support the new class.
For example:
Bad:
// Don't do this:
void PrintName(Base *b, ostream &o)
{
if (dynamic_cast<DerivedA *>(b) != NULL)
o << "Derived A";
if (dynamic_cast<DerivedB *>(b) != NULL)
o << "Derived B";
if (dynamic_cast<DerivedC *>(b) != NULL)
o << "Derived C";
}
Better:
void PrintName(Base *b, ostream &o)
{
o << b->GetName();
}
This is obviously eliding checking for null, and using smart pointers, etc.. Likewise, if you're querying the type to choose between different behaviours, you need to ask why you're doing something different for each type, and move that behaviour decision into the object.
Bad:
// Don't do this:
void ObjectBase::ApplyForceToObject(const Force &f)
{
if (dynamic_cast<Wall*>(this) != NULL
|| dynamic_cast<Floor*>(b) != NULL)
{
// Do nothing
}
else
{
// Accelerate object
}
}
Better:
void ObjectBase::ApplyForceToObject(const Force &f)
{
if (IsFixedObject())
{
// Do nothing
}
else
{
// Accelerate object
}
}
...
bool ObjectBase::IsFixedObject() { return false; }
bool Wall::IsFixedObject() { return true; }
bool Floor::IsFixedObject() { return true; }

In modern C++ there is no point.
Frameworks dating from before the 1998 standardization may offer an IsA function.
E.g. as I recall there is such functionality in MFC.
Also, as you note, when dealing with objects implemented in other languages (with types not represented by C++ types) it may conceivably be useful.
Cheers & hth.,

Because dynamic-cast relies on RTTI, and this can hurt performance. It is also a bit more convinient and reliable.

Sometimes you dont have RTTI ( maybe you're working on a memory/cpu constrained system and disabling RTTI is the mandated solution) In that case you don't have dynamic_cast available to you. If you want to use something similar to RTTI you usually end up with solutions that are IsA() with static_cast.
Another possible use for an IsA() function is when you don't know all your classes at compile-time (maybe they've been loaded from shared library), or you dont want to list all the types explicitly. This lets you write things like
handleInstance( Instance * i )
{
//libs has been filled through loading dynamic libraries.
for( auto it = libs.begin() ; it!=libs.end() ; ++it )
{
if( i->IsA( it->type_key ) )
{
it->process( i );
}
}
}
Though in this case I might turn the test condition inside out like
if( it->can_process( i ) )
and can_process would be free to use dynamic_cast.

An example of how to find run time type information without RTTI
MFC uses a function called IsKindOf() for run time type information. The method MFC uses to find type information is somewhat like the example below.
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
#define RUNTIME_OBJ(class_name) (class##class_name)
struct RunTimeClass
{
string name;
};
class base
{
static RunTimeClass RUNTIME_OBJ(base); //watch the naming
public:
bool IsExactKind(RunTimeClass* pRTclass)
{
if(pRTclass == GetRunTimeClass())
{
return true;
}
return false;
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(base);
}
virtual RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(base);
}
virtual ~base() = 0;
};
class derived: public base
{
static RunTimeClass RUNTIME_OBJ(derived); //watch the naming
public:
RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(derived);
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(derived);
}
};
class derived2: public derived
{
static RunTimeClass RUNTIME_OBJ(derived2); //watch the naming
public:
RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(derived2);
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(derived2);
}
};
In the cpp file
RunTimeClass base::classbase = {"base"}; //not using the macro RUNTIME_OBJ
RunTimeClass derived::classderived = {"derived"}; //not using the macro RUNTIME_OBJ
RunTimeClass derived2::classderived2 = {"derived2"}; //not using the macro RUNTIME_OBJ
base::~base() {}
void main()
{
derived *ptrDer = new derived();
bool isder = ptrDer->IsExactKind(RUNTIME_CLASS(derived));
derived2 *ptrDer2 = new derived2();
isder = ptrDer2->IsExactKind(RUNTIME_CLASS(derived2));
delete ptrDer;
delete ptrDer2;
}
Note that this can only find if the object is of the exact class type. To add type information you just need to inherit from base and add a Runtimeclass variable and implement two functions getthisclass(), getruntimeclass(). MFC use CObject as the base class which provides similiar functionality. Also, there are more macros to make your life easier. IsKindOF() function in MFC walk thourgh the entire hierarchy and find out the object "is a" type of class(which is not there in my scaled down version). You can see this is somewhat similiar to RTTI, hence I guess there is no perfomance difference. It is there in MFC because it was there before RTTI.
So, if there is an IsA() function which perfoms better than RTTI, I would like to see the implementation.

Related

Declaring a reference to a namespace at runtime in c++

I have a c++ program in which I:
Have a class which contains, as members, function handles, say void (*foo) and void (*bar)
Have a collection of namespaces, each defining functions of the same name, e.g.:
namespace1 contains functions void foo() and void bar()
namespace2 also contains functions void foo() and void bar()
At run-time, I would like the user to be able to pass a variable, say choice, which indicates the chosen namespace. The functions in the class would then be mapped to the corresponding functions in the appropriate namespace.
Currently, I'm using something along the following lines:
if (choice == "namespace1") {
my_class.foo = &(namespace1::foo);
my_class.bar = &(namespace1::bar);
} else if (choice == "namespace2") {
my_class.foo = &(namespace2::foo);
my_class.bar = &(namespace2::bar);
}
This works well, but becomes rather cumbersome when my list of available namespaces increases and given that each namespace provides 9 functions that I would like to pass into the class.
Are there ways that I can tidy this up? My first thought was something like:
if (choice == "namespace1") {
my_namespace = namespace1;
} else if (choice == "namespace2") {
my_namespace = namespace2;
}
my_class.foo = &(my_namespace::foo);
my_class.bar = &(my_namespace::bar);
But, if I understand correctly, I cannot use namespaces as variables.
Is there a better way to formulate this? As structured, is this poor style and, is there a more standard way to go about this?
Thank you for any insights that you might have!
You should be aware of the phases of compilation, at least approximately. Names simply do not exist at runtime. Your existing code works by creating pointers for each and every name within each namespace.
The standard solution is to define an interface.
class IFooBar {
virtual void foo() = 0;
virtual void bar() = 0;
// Other 7 functions.
};
This allows each namespace to define one class instead of 9 functions.
Chances are that the compiler behind the scenes creates a "vtable", an array of function pointers, to implement this interface. This would be approximately the same as you do now, but then automated and without the chance of copy-paste errors.
I suggest using traits.
template<Context C>
struct context;
template<NAMESPACE_1> struct context<> {
static foo_return_t foo(...) {
return namespace1::foo (...);
}
static bar_return_t bar(...) {
return namespace1::bar (...);
}
};
template<NAMESPACE_2> struct context<> {
static foo_return_t foo(...) {
return namespace2::foo (...);
}
static bar_return_t bar(...) {
return namespace2::bar (...);
}
};
Then use like so:
foo_ret_t a;
bar_ret_t b;
if (choice == "namespace1") {
a = context<NAMESPACE_1>::foo(...);
b = context<NAMESPACE_1>::bar(...);
} else if (choice == "namespace1") {
a = context<NAMESPACE_2>::foo(...);
b = context<NAMESPACE_2>::bar(...);
}
Your problem is that the stuff is evaluated at runtime.
To expand on the the answer by #MSalters ...
There is a design pattern that addresses this situation. It is called the Dependency Injection Pattern.
Your class (where you are trying to store foo and bar) is the client.
The namespaces contain classes that implement the interface.
A dependency injector will need to inject the dependency (a pointer to one of the concrete classes in the namespaces) into the client.

Automate LLVM style RTTI code

For a specific class hiararchy I need to know if a base class reference is an instance of a specific derived class.
For different reasons, I can't use standard C++ RTTI here and I need to implement a custom instanceof mechanism.
The LLVM-stle RTTI would suite my needs but I was wondering if it would exists a way (somehow using templates) to automate the implementation of the classof method?
Are there other/simpler implementation of such mechanism that would allow to know if a base class is an instance of a derived class?
My constraints:
I don't have multiple inheritance but I have several level of inheritance.
Inpact on memory footprint must be as minimal as possible and it is not possible to perform dynamic allocation.
I was wondering if it would exists a way (somehow using templates) to automate the implementation of the classof method?
Yes, there are ways to automate the classof method, I really don't understand why the LLVM page would demonstrate a hand-rolled set of classof methods, since it is so much more scalable if you automate that very simple process.
Here is a very basic solution:
class TypedObject {
public:
virtual ~TypedObject() { };
virtual int getClassId() const { return 0; };
static int getStaticClassId() { return 0; };
virtual bool isOfType(int aID) const { return (aID == 0); };
template <typename T>
bool isOfClass() const { return isOfType( T::getStaticClassId() ); };
};
The runtime-cast (i.e., dynamic_cast) functions would look like this:
template <typename T>
T* runtime_ptr_cast(TypedObject* p) {
if( (p) && (p->isOfClass<T>()) )
return static_cast<T*>( p );
return NULL;
};
template <typename T>
typename std::enable_if<
std::is_const< T >::value,
T* >::type runtime_ptr_cast(const TypedObject* p) {
if( (p) && (p->isOfClass<T>()) )
return static_cast<T*>( p );
return NULL;
};
then, all you need are MACROs to automate the creation of the virtual and static functions:
#define MY_RTTI_SYSTEM_CREATE_TYPE_1_BASE( NEWCLASSID, BASECLASSNAME ) \
public: \
virtual int getClassId() const { return NEWCLASSID; }; \
static int getStaticClassId() { return NEWCLASSID; }; \
\
virtual bool isOfType(int aID) const { \
return ((aID == NEWCLASSID) || BASECLASSNAME::isOfType(aID)); \
};
Then, you can create a new class like this:
class Foo : public TypedObject {
// ... some code, as usual ...
// call the macro with a given ID number and the name of the base-class:
MY_RTTI_SYSTEM_CREATE_TYPE_1_BASE(1, TypedObject)
};
Which leads to:
int main() {
Foo f;
TypedObject* b = &f;
// check the type:
if( b->isOfClass<Foo>() )
std::cout << "b is indeed for class Foo!" << std::endl;
// make a dynamic cast:
Foo* pf = runtime_ptr_cast<Foo>( b );
if( pf )
std::cout << "cast to 'Foo*' was successful!" << std::endl;
const TypedObject* cb = b;
const Foo* cpf = runtime_ptr_cast<const Foo>( cb );
if( cpf )
std::cout << "cast to 'const Foo*' was successful!" << std::endl;
Foo* pf2 = runtime_ptr_cast<Foo>( cb ); // ERROR: no such function (invalid cast).
};
And of course, you can extend this to multiple inheritance too, by just creating more MACROs for registering the types. There are also countless variations on this scheme (personally, in my implementation, I register the types to a global repository and give access to factory-functions too).
I don't think that there is any practical way to avoid having to use a MACRO-call in each class that you create. I've thought about it for a while (some time ago, as I was making my own) and I concluded that the easiest and cleanest solution was to have a MACRO-call in the classes (even though I have great disdain for MACROs in general). But I don't know, maybe others have a better (template-based) solution to this that doesn't cause too much clutter or isn't too intrusive. I've been using this scheme for years, and it is very nice and clean.
I don't have multiple inheritance but I have several level of inheritance.
The above scheme works for any level of inheritance (i.e., it is a scalable solution). It can also easily be adapted to multiple-inheritance if one day you desire to do so.
Impact on memory footprint must be as minimal as possible
I know that LLVM prefers a solution without any virtual functions and using instead an integral-id data member in the base-classes. It becomes a bit harder to achieve the same kind of functionality as above with that kind of scheme (but possible). It's much easier with virtual functions, which occupy only the space of one pointer (vtable pointer) which often isn't much bigger than an integral-id data member. And if classes are already polymorphic, the cost is nothing at all. And, of course, the above is much lighter-weight than the built-in C++ RTTI. So, unless you really want to squeeze those few bytes that you could spare with an integral-id (or enum) solution, I would recommend you go with a solution based on virtual functions like I showed above.
it is not possible to perform dynamic allocation.
Dynamic allocation is not needed in general. Only the more complicated (and feature-rich) RTTI implementations would require some dynamic allocation. If all you want is to be able to do "classof()" (and thus, dynamic-casts), no dynamic memory allocation is needed, for sure.
You want some kind of tree like data structure as a global variable to store your class hierarchy
class Foo : public Foo_Parent {
IS_PART_OF_HIERARCHY
public:
Foo();
...
}
#define IS_PART_OF_HIERARCHY
private:
static Hierarchy<string> *node;
public:
bool isChildOf( string parent ) const;
bool isParentOf( string child ) const;
In .cpp file
INSERT_INTO_HIERARCHY( Foo, Foo_Parent )
Foo::Foo() {}
....
#define INSERT_INTO_HIERARCHY( class_name, parent_class_name )
Hierarchy<string> class_name::node = classes_hierarchy.insertAfter( #parent_class_name );
bool class_name::isChildOf const( string ) {
auto *node = class_name::node;
// traverse the parents of node
}
bool class_name::isParentOf const( string ) {
auto *node = class_name::node;
// traverse the children of node
}
I can't find a hierarchy class in the STL, it is little tricky to implement one, I don't know if it is worth the effort.

Practical use of dynamic_cast?

I have a pretty simple question about the dynamic_cast operator. I know this is used for run time type identification, i.e., to know about the object type at run time. But from your programming experience, can you please give a real scenario where you had to use this operator? What were the difficulties without using it?
Toy example
Noah's ark shall function as a container for different types of animals. As the ark itself is not concerned about the difference between monkeys, penguins, and mosquitoes, you define a class Animal, derive the classes Monkey, Penguin, and Mosquito from it, and store each of them as an Animal in the ark.
Once the flood is over, Noah wants to distribute animals across earth to the places where they belong and hence needs additional knowledge about the generic animals stored in his ark. As one example, he can now try to dynamic_cast<> each animal to a Penguin in order to figure out which of the animals are penguins to be released in the Antarctic and which are not.
Real life example
We implemented an event monitoring framework, where an application would store runtime-generated events in a list. Event monitors would go through this list and examine those specific events they were interested in. Event types were OS-level things such as SYSCALL, FUNCTIONCALL, and INTERRUPT.
Here, we stored all our specific events in a generic list of Event instances. Monitors would then iterate over this list and dynamic_cast<> the events they saw to those types they were interested in. All others (those that raise an exception) are ignored.
Question: Why can't you have a separate list for each event type?
Answer: You can do this, but it makes extending the system with new events as well as new monitors (aggregating multiple event types) harder, because everyone needs to be aware of the respective lists to check for.
A typical use case is the visitor pattern:
struct Element
{
virtual ~Element() { }
void accept(Visitor & v)
{
v.visit(this);
}
};
struct Visitor
{
virtual void visit(Element * e) = 0;
virtual ~Visitor() { }
};
struct RedElement : Element { };
struct BlueElement : Element { };
struct FifthElement : Element { };
struct MyVisitor : Visitor
{
virtual void visit(Element * e)
{
if (RedElement * p = dynamic_cast<RedElement*>(e))
{
// do things specific to Red
}
else if (BlueElement * p = dynamic_cast<BlueElement*>(e))
{
// do things specific to Blue
}
else
{
// error: visitor doesn't know what to do with this element
}
}
};
Now if you have some Element & e;, you can make MyVisitor v; and say e.accept(v).
The key design feature is that if you modify your Element hierarchy, you only have to edit your visitors. The pattern is still fairly complex, and only recommended if you have a very stable class hierarchy of Elements.
Imagine this situation: You have a C++ program that reads and displays HTML. You have a base class HTMLElement which has a pure virtual method displayOnScreen. You also have a function called renderHTMLToBitmap, which draws the HTML to a bitmap. If each HTMLElement has a vector<HTMLElement*> children;, you can just pass the HTMLElement representing the element <html>. But what if a few of the subclasses need special treatment, like <link> for adding CSS. You need a way to know if an element is a LinkElement so you can give it to the CSS functions. To find that out, you'd use dynamic_cast.
The problem with dynamic_cast and polymorphism in general is that it's not terribly efficient. When you add vtables into the mix, it only get's worse.
When you add virtual functions to a base class, when they are called, you end up actually going through quite a few layers of function pointers and memory areas. That will never be more efficient than something like the ASM call instruction.
Edit: In response to Andrew's comment bellow, here's a new approach: Instead of dynamic casting to the specific element type (LinkElement), instead you have another abstract subclass of HTMLElement called ActionElement that overrides displayOnScreen with a function that displays nothing, and creates a new pure virtual function: virtual void doAction() const = 0. The dynamic_cast is changed to test for ActionElement and just calls doAction(). You'd have the same kind of subclass for GraphicalElement with a virtual method displayOnScreen().
Edit 2: Here's what a "rendering" method might look like:
void render(HTMLElement root) {
for(vector<HTLMElement*>::iterator i = root.children.begin(); i != root.children.end(); i++) {
if(dynamic_cast<ActionElement*>(*i) != NULL) //Is an ActionElement
{
ActionElement* ae = dynamic_cast<ActionElement*>(*i);
ae->doAction();
render(ae);
}
else if(dynamic_cast<GraphicalElement*>(*i) != NULL) //Is a GraphicalElement
{
GraphicalElement* ge = dynamic_cast<GraphicalElement*>(*i);
ge->displayToScreen();
render(ge);
}
else
{
//Error
}
}
}
Operator dynamic_cast solves the same problem as dynamic dispatch (virtual functions, visitor pattern, etc): it allows you to perform different actions based on the runtime type of an object.
However, you should always prefer dynamic dispatch, except perhaps when the number of dynamic_cast you'd need will never grow.
Eg. you should never do:
if (auto v = dynamic_cast<Dog*>(animal)) { ... }
else if (auto v = dynamic_cast<Cat*>(animal)) { ... }
...
for maintainability and performance reasons, but you can do eg.
for (MenuItem* item: items)
{
if (auto submenu = dynamic_cast<Submenu*>(item))
{
auto items = submenu->items();
draw(context, items, position); // Recursion
...
}
else
{
item->draw_icon();
item->setup_accelerator();
...
}
}
which I've found quite useful in this exact situation: you have one very particular subhierarchy that must be handled separately, this is where dynamic_cast shines. But real world examples are quite rare (the menu example is something I had to deal with).
dynamic_cast is not intended as an alternative to virtual functions.
dynamic_cast has a non-trivial performance overhead (or so I think) since the whole class hierarchy has to be walked through.
dynamic_cast is similar to the 'is' operator of C# and the QueryInterface of good old COM.
So far I have found one real use of dynamic_cast:
(*) You have multiple inheritance and to locate the target of the cast the compiler has to walk the class hierarchy up and down to locate the target (or down and up if you prefer). This means that the target of the cast is in a parallel branch in relation to where the source of the cast is in the hierarchy. I think there is NO other way to do such a cast.
In all other cases, you just use some base class virtual to tell you what type of object you have and ONLY THEN you dynamic_cast it to the target class so you can use some of it's non-virtual functionality. Ideally there should be no non-virtual functionality, but what the heck, we live in the real world.
Doing things like:
if (v = dynamic_cast(...)){} else if (v = dynamic_cast(...)){} else if ...
is a performance waste.
Casting should be avoided when possible, because it is basically saying to the compiler that you know better and it is usually a sign of some weaker design decission.
However, you might come in situations where the abstraction level was a bit too high for 1 or 2 sub-classes, where you have the choice to change your design or solve it by checking the subclass with dynamic_cast and handle it in a seperate branch. The trade-of is between adding extra time and risk now against extra maintenance issues later.
In most situations where you are writing code in which you know the type of the entity you're working with, you just use static_cast as it's more efficient.
Situations where you need dynamic cast typically arrive (in my experience) from lack of foresight in design - typically where the designer fails to provide an enumeration or id that allows you to determine the type later in the code.
For example, I've seen this situation in more than one project already:
You may use a factory where the internal logic decides which derived class the user wants rather than the user explicitly selecting one. That factory, in a perfect world, returns an enumeration which will help you identify the type of returned object, but if it doesn't you may need to test what type of object it gave you with a dynamic_cast.
Your follow-up question would obviously be: Why would you need to know the type of object that you're using in code using a factory?
In a perfect world, you wouldn't - the interface provided by the base class would be sufficient for managing all of the factories' returned objects to all required extents. People don't design perfectly though. For example, if your factory creates abstract connection objects, you may suddenly realize that you need to access the UseSSL flag on your socket connection object, but the factory base doesn't support that and it's not relevant to any of the other classes using the interface. So, maybe you would check to see if you're using that type of derived class in your logic, and cast/set the flag directly if you are.
It's ugly, but it's not a perfect world, and sometimes you don't have time to refactor an imperfect design fully in the real world under work pressure.
The dynamic_cast operator is very useful to me.
I especially use it with the Observer pattern for event management:
#include <vector>
#include <iostream>
using namespace std;
class Subject; class Observer; class Event;
class Event { public: virtual ~Event() {}; };
class Observer { public: virtual void onEvent(Subject& s, const Event& e) = 0; };
class Subject {
private:
vector<Observer*> m_obs;
public:
void attach(Observer& obs) { m_obs.push_back(& obs); }
public:
void notifyEvent(const Event& evt) {
for (vector<Observer*>::iterator it = m_obs.begin(); it != m_obs.end(); it++) {
if (Observer* const obs = *it) {
obs->onEvent(*this, evt);
}
}
}
};
// Define a model with events that contain data.
class MyModel : public Subject {
public:
class Evt1 : public Event { public: int a; string s; };
class Evt2 : public Event { public: float f; };
};
// Define a first service that processes both events with their data.
class MyService1 : public Observer {
public:
virtual void onEvent(Subject& s, const Event& e) {
if (const MyModel::Evt1* const e1 = dynamic_cast<const MyModel::Evt1*>(& e)) {
cout << "Service1 - event Evt1 received: a = " << e1->a << ", s = " << e1->s << endl;
}
if (const MyModel::Evt2* const e2 = dynamic_cast<const MyModel::Evt2*>(& e)) {
cout << "Service1 - event Evt2 received: f = " << e2->f << endl;
}
}
};
// Define a second service that only deals with the second event.
class MyService2 : public Observer {
public:
virtual void onEvent(Subject& s, const Event& e) {
// Nothing to do with Evt1 in Service2
if (const MyModel::Evt2* const e2 = dynamic_cast<const MyModel::Evt2*>(& e)) {
cout << "Service2 - event Evt2 received: f = " << e2->f << endl;
}
}
};
int main(void) {
MyModel m; MyService1 s1; MyService2 s2;
m.attach(s1); m.attach(s2);
MyModel::Evt1 e1; e1.a = 2; e1.s = "two"; m.notifyEvent(e1);
MyModel::Evt2 e2; e2.f = .2f; m.notifyEvent(e2);
}
Contract Programming and RTTI shows how you can use dynamic_cast to allow objects to advertise what interfaces they implement. We used it in my shop to replace a rather opaque metaobject system. Now we can clearly describe the functionality of objects, even if the objects are introduced by a new module several weeks/months after the platform was 'baked' (though of course the contracts need to have been decided on up front).

How to return different classes from one function?

I have a question, though it is not limited to C++. How to return totally different class from one function?
f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
For example, I have two balls in the space, according to the position and the size, there are three situations for the two balls to intersect with each other, i.e, non-intersection, at point, a and circle. How can I return different class in one function?
Thanks.
If you can afford Boost then this sounds like a perfect application for Boost.Variant.
struct NoIntersection {
// empty
};
struct Point {
// whatever
};
struct Circle {
// whatever
};
typedef boost::variant<NoIntersection, Point, Circle> IntersectionResult;
IntersectionResult intersection_test() {
if(some_condition){
return NoIntersection();
}
if(other_condition){
return Point(x, y);
}
if(another_condition){
return Circle(c, r);
}
throw std::runtime_error("unexpected");
}
You then process your result with a static visitor:
struct process_result_visitor : public boost::static_visitor<> {
void operator()(NoIntersection) {
std::cout << "there was no intersection\n";
}
void operator()(Point const &pnt) {
std::cout << "there was a point intersection\n";
}
void operator()(Circle const &circle) {
std::cout << "there was a circle intersection\n";
}
};
IntersectionResult result = intersection_test();
boost::apply_visitor(process_result_visitor(), result);
EDIT: The visitor class must derive from boost::static_visitor
UPDATE: Prompted by some critical comments I've written a little benchmark program. Four approaches are compared:
boost::variant
union
class hierarchy
boost::any
These are the results in my home computer, when I compile in release mode with default optimizations (VC08):
test with boost::variant took 0.011 microseconds
test with union took 0.012 microseconds
test with hierarchy took 0.227 microseconds
test with boost::any took 0.188 microseconds
Using boost::variant is faster than a union and leads (IMO) to the most elegant code. I'd guess that the extremely poor performance of the class hierarchy approach is due to the need to use dynamic memory allocations and dynamic dispatch. boost::any is neither fast nor especially elegant so I wouldn't consider it for this task (it has other applications though)
The classes you want to return should be derived from a common base class. So, you can return the base type. For Example (this is not a code, just marking the pattern, you can use an interface if your language supports this abstraction or abstract class for example. If you use C++ you will have to return a pointer of the common class):
class A : public Common
{
..
}
class B : public Common
{
..
}
class C : public Common
{
..
}
Common f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
In addition to #Manuel's Boost.Variant suggestion, take a look at Boost.Any: has similar purpose as Boost.Variant but different tradeoffs and functionality.
boost::any is unbounded (can hold any type) while boost::variant is bounded (supported types is encoded in variant type, so it can hold only values of these types).
// from Beyond the C++ Standard Library: An Introduction to Boost
// By Björn Karlsson
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "boost/any.hpp"
class A {
public:
void some_function() { std::cout << "A::some_function()\n"; }
};
class B {
public:
void some_function() { std::cout << "B::some_function()\n"; }
};
class C {
public:
void some_function() { std::cout << "C::some_function()\n"; }
};
int main() {
std::cout << "Example of using any.\n\n";
std::vector<boost::any> store_anything;
store_anything.push_back(A());
store_anything.push_back(B());
store_anything.push_back(C());
// While we're at it, let's add a few other things as well
store_anything.push_back(std::string("This is fantastic! "));
store_anything.push_back(3);
store_anything.push_back(std::make_pair(true, 7.92));
void print_any(boost::any& a);
// Defined later; reports on the value in a
std::for_each(
store_anything.begin(),
store_anything.end(),
print_any);
}
void print_any(boost::any& a) {
if (A* pA=boost::any_cast<A>(&a)) {
pA->some_function();
}
else if (B* pB=boost::any_cast<B>(&a)) {
pB->some_function();
}
else if (C* pC=boost::any_cast<C>(&a)) {
pC->some_function();
}
}
In order to be able to do anything useful with the result, you have to return an object which has a common baseclass. In your case you might want to let A, B, and C inherit from a common "intersection-class"; a class which is common for all objects which represents some form of intersection. Your function f would then return an object of this type.
The classes you want to return should have a common parent class or interface.
If those classes do not have anything in common, that, I suppose, is untrue, you can return object.
This feature is also known as polymorphism.
In c++ base class pointer can point to derived class object. We can make use of this fact to code a function that meets your requirements:
class shape{};
class circle: public shape
{};
class square: public shape
{};
shape* function(int i){ // function returning a base class pointer.
switch(i) {
case 1: return new circle();
case 2: return new square();
}
}
There is one other option available. You can return a union of pointers to objects along with a tag that tells the caller which member of the union is valid. Something like:
struct result {
enum discriminant { A_member, B_member, C_member, Undefined } tag;
union result_data {
A *a_object;
B *b_object;
C *c_object;
} data;
result(): tag(Undefined) {}
explicit result(A *obj): tag(A_member) { data.a_object = obj; }
explicit result(B *obj): tag(B_member) { data.b_object = obj; }
explicit result(C *obj): tag(C_member) { data.c_object = obj; }
};
I would probably use Boost.variant as suggested by Manuel if you have the option.
You can't. You can only return a base pointer to different derived classes. If this is absolutely, 100% needed, you can use exceptions as a ugly hack, but that's obviously not recommended at all.
Even if you could return three different types of objects from the function, what would you do with the result? You need to do something like:
XXX ret_val = getIntersection();
If getIntersection returned three different types of objects, XXX would have to change based on what getIntersection was going to return. Clearly this is quite impossible.
To deal with this, you can define one type that defines enough to cover all the possibilities:
class Intersection {
enum { empty, point, circle, sphere};
point3D location;
size_t radius;
};
Now getIntersection() can return an Intersection that defines what kind of intersection you have (and BTW, you need to consider the fourth possibility: with two spheres of the same radius and same center point, the intersection will be a sphere) and the size and location of that intersection.
The limitation is based on the declared return type of your method. Your code states:
f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
When in reality the compiler requires something like this:
FooType f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
It must be possible to convert the A, B, and C to a FooType, typically through simple inheritance, though I won't get into the differences between subclasses vs subtyping.
There are approaches that can get around this. You could create a class or struct (C++) which has fields for each different type of possible return and use some flag field to indicate which field is the actual returned value.
class ReturnHolder {
public int fieldFlag;
public TypeA A;
public TypeB B;
public TypeC C;
}
The enum example in another answer is more of the same. The reason why that is a hack is that the code that handles the return from this method will have to have lots of code to handle each of the different possibilites, like so
main(){
FooType *x = new FooType();
ReturnHolder ret = x.f();
switch (ret.fieldFlag)
case: 1
//read ret.A
case: 2
//read ret.B
case: 3
//read ret.C
}
And that's without even going into trying to do it with Exceptions which introduce even bigger problems. Maybe I'll add that in later as an edit.
And by the way, as you said that question "is not limited to C++":
1) dynamic languages, of course, make it piece of cake:
# python
def func(i):
if i == 0:
return 0
elif i == 1:
return "zero"
else
return ()
2) some functional languages (Haskell, OCaml, Scala, F#) provide nice built-in variants that are called Algebraic Data Types (article has good samples).
In languages that reflection, it is easier to achieve. In cpp, if you have a standard set of classes to be returned (pointers), create an enumeration and return the enum value. Using this value you can infer the class type. This is a generic way in case there is no common parent class
You really shouldn't want to be doing that, and should really come up with a better design instead of forcing a square peg in a round hole. And with most languages you can't do it at all, by design. You will never really know what you are working with, and neither will the compiler ahead of time, ensuring extra bugs and weird behavior and incomprehensibility.

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.