C++ Rtti Viable Examples

C++ and serialization: is there any way to do some kind of introspection?

It isn't used (since it doesn't exist), there's no code examples (since it doesn't exist), and there's no reason to attempt to use it (since it doesn't exist).

The closest you can get is RTTI/dynamic_cast. But that's not really introspection.

C++ double dispatch extensible without RTTI

The first thing to realize is that double (or higher order) dispatch doesn't scale. With single
dispatch, and n types, you need n functions; for double dispatch n^2, and so on. How you
handle this problem partially determines how you handle double dispatch. One obvious solution is to
limit the number of derived types, by creating a closed hierarchy; in that case, double dispatch can
be implemented easily using a variant of the visitor pattern. If you don't close the hierarchy,
then you have several possible approaches.

If you insist that every pair corresponds to a function, then you basically need a:

std::map<std::pair<std::type_index, std::type_index>, void (*)(Base const& lhs, Base const& rhs)>
dispatchMap;

(Adjust the function signature as necessary.) You also have to implement the n^2 functions, and
insert them into the dispatchMap. (I'm assuming here that you use free functions; there's no
logical reason to put them in one of the classes rather than the other.) After that, you call:

(*dispatchMap[std::make_pair( std::type_index( typeid( obj1 ) ), std::type_index( typeid( obj2 ) )])( obj1, obj2 );

(You'll obviously want to wrap that into a function; it's not the sort of thing you want scattered
all over the code.)

A minor variant would be to say that only certain combinations are legal. In this case, you can use
find on the dispatchMap, and generate an error if you don't find what you're looking for.
(Expect a lot of errors.) The same solution could e used if you can define some sort of default
behavior.

If you want to do it 100% correctly, with some of the functions able to handle an intermediate class
and all of its derivatives, you then need some sort of more dynamic searching, and ordering to
control overload resolution. Consider for example:

            Base
/ \
/ \
I1 I2
/ \ / \
/ \ / \
D1a D1b D2a D2b

If you have an f(I1, D2a) and an f(D1a, I2), which one should be chosen. The simplest solution
is just a linear search, selecting the first which can be called (as determined by dynamic_cast on
pointers to the objects), and manually managing the order of insertion to define the overload
resolution you wish. With n^2 functions, this could become slow fairly quickly, however. Since
there is an ordering, it should be possible to use std::map, but the ordering function is going to
be decidedly non-trivial to implement (and will still have to use dynamic_cast all over the
place).

All things considered, my suggestion would be to limit double dispatch to small, closed hierarchies,
and stick to some variant of the visitor pattern.

C++ Downcasting to Derived Class based off Variable

If they've virtual functions, then use dynamic_cast:

t = dynamic_cast<Triangle*>(shape);
if ( t )
{
//use t
}

But take a note: you should try defining the classes and virtual functions in such a way that you would hardly need to use dynamic_cast. Prefer well-defined interface, and polymorphism, in general.

Here is one example,

class Shape
{
public:
virtual ~Shape() {} //destructor must be virtual - important!
virtual double Area() const = 0;
};

class Triangle : public Shape
{
public:
Triangle(double a, double b, double c);
virtual double Area() const
{
//calculate area and return it!
}
};

Shape *s = new Triangle(10, 20, 30);
double aread = s->Area(); //calls Triangle::Area()

No need to use shapeType variable.

Speeding up virtual function calls in gcc

It's sometimes instructive to consider how you'd write the code in good old 'C' if you didn't have C++'s syntactic sugar available. Sometimes the answer isn't using an indirect call. See this answer for an example.



Related Topics



Leave a reply



Submit