Gabriel Cuvillier
Gabriel Cuvillier

Reputation: 3663

How to represent basic Mixin behavior in C++

Consider an existing C++ class hierarchy: one root class, many children classes forming a direct acyclic graph.

I would like to add a method to the root class, and possibly override it in some children. But the problem is that it is forbidden for me to modify these existing classes (3rd party library, project policy, closed source, etc..).

A mixin/extension class would then be a good solution. But it is not trivially feasible in C++.

The quick and dirty solution is to write a function that dispatches on the type of the object using the dynamic_cast operator, and performing the wanted code to each type of the hierarchy. But it is somewhat a bad practice, since it is error prone to write, it breaks encapsulation, and does not support safely future changes.

I am thinking about maintaining some kind of hash-table somewhere with the definition {rtti type id, function to call}", and use that as a fake VTable for the function I want to write and override. But I'm not sure if it would be better...

Any other ideas? Runtime VTable alteration? Template meta-programming solution? Other?

Don't forget: I definitively can't change the original classes (neither headers nor implementation).

Upvotes: 3

Views: 740

Answers (3)

Borislav Stanimirov
Borislav Stanimirov

Reputation: 1659

Actually I'm writing a library that does just that: allows you to compose and modify types from existing classes at runtime, with the cost of not being able to call the methods as... er methods, but as external functions with first argument this. It's non-intrusive so you don't need to modify the existing classes in any way.

Code: https://github.com/iboB/boost.mixin

Doc: http://ibob.github.io/boost.mixin/

Hope it helps.

PS. It's called Boost.Mixin, because I intend to submit it to Boost, but it's NOT part of Boost yet.

Upvotes: 2

Matthieu M.
Matthieu M.

Reputation: 300439

If you cannot alter the original hierarchy, then template meta-programming is unlikely to help. Remember it's based on compile-time information.

Altering the vtable seems like an extremely bad idea, it's obviously non-portable and presume that you somewhat know its physical layout... even if you get it right it will be a maintenance nightmare.

I quite like the std::map<type_info, Func> idea. std::type_info::before offers you all is needed for implementation (don't rely on the name or address).

Upvotes: 2

wilhelmtell
wilhelmtell

Reputation: 58725

Write a free function.

void vfunc(base& param);

// ...
base b;
vfunc(b);

deriv0 d0;
vfunc(d0);

Upvotes: 1

Related Questions