2011-04-15 44 views
3

基本密新行为考虑现有的C++类层次结构:一个根类,很多孩子班级形成了向无环图。如何代表C++

我想一个方法添加到根类,并可能覆盖它在一些儿童。 但问题是,它是被禁止的,我修改这些现有的类(第三方库,项目政策,封闭源代码,等等)。然后

一个混合/扩展类将是一个很好的解决方案。但它在C++中并不可行。

的快速和肮脏的解决方案是将写上使用 的的dynamic_cast操作员,以及执行想要的代码给每个类型的层次结构的对象的类型将调度功能。但这是一种不好的做法,因为 它容易出错,它破坏了封装,并且不支持安全的将来更改。

我的想法与定义保持某种哈希表的地方{RTTI类型ID,功能调用}”,并用它作为 一个假的虚函数表因为我想写的功能和重写但我不知道这是否会更好......

任何其他的想法运行虚函数表改造模板元编程解决方案的其他

不要忘了:????我明确不能改变原来的类(既没有标题也没有实现)。

回答

2

如果您无法更改原始层次结构,那么模板元编程不太可能有所帮助。请记住它基于编译时信息。

改变vtable看起来是一个非常糟糕的主意,它显然是不可移植的,并假设你有点了解它的物理布局......即使你做对了,它也将是一个维护噩梦。

我很喜欢std::map<type_info, Func>想法。 std::type_info::before为您提供实施所需的一切(不要依赖名称或地址)。

+0

好吧,然后我将使用std :: map 系统。感谢advince :: before。 – 2011-04-18 18:03:31

1

写一个免费的功能。

void vfunc(base& param); 

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

deriv0 d0; 
vfunc(d0); 
+1

那就是我所做的,并且在类型上使用dynamic_cast来模拟方法覆盖。但我认为这不是一个很好的做事方式。我正在寻找的是一个更干净的方式来做到这一点(比如运行时Mixins等) – 2011-04-15 12:42:16

+0

我不明白。你为什么需要'dynamic_cast'?如果你需要多态,那么上面的函数签名就是你所需要的。如果您需要编译时多态性,请将其作为模板。如果您希望层次结构中每个类的特定行为,并且没有其他类,则会重载该函数。 – wilhelmtell 2011-04-15 12:50:17

+2

除了如果我重载“deriv0”的函数,但只有一个指向“base”(可能是“deriv0”或“deriv1”等的实例)的指针,重载函数将不会被调用,函数调用仅在编译时类型上调度。 – 2011-04-15 13:10:36

2

其实我在写,不只是一个库:可让您撰写并在运行时从现有的类修改的类型,与不能够调用的方法是......呃方法的成本,但由于外部函数的第一个参数this。这是非侵入式的,所以你不需要以任何方式修改现有的类。

代码:https://github.com/iboB/boost.mixin

文件:http://ibob.github.io/boost.mixin/

希望它帮助。

PS。它被称为Boost.Mixin,因为我打算将它提交给Boost,但它不是Boost的一部分。