有没有办法避免在存储(子)指针时声明虚方法?

时间:2013-03-10 08:03:25

标签: c++ pointers virtual

我最近遇到了一个恼人的问题,我对自己的解决方法不满意:我有一个程序,它维护一个指向基类的指针向量,并且我存储了所有类型的子对象指针。现在,每个子类都有自己的方法,主程序可能会调用这些方法,这取决于对象的类型(注意,它们都大量使用基类的常用方法,因此这证明了继承)。

我发现有一个“对象标识符”可以检查类类型(然后调用方法或不调用),这已经不是很漂亮了,但这不是主要的不便之处。主要的不便之处在于,如果我想实际上能够使用基类指针调用派生类方法(或者甚至只是将指针存储在指针数组中),那么需要在基础中将派生方法声明为虚拟类。

从C ++编码的角度来看是有意义的......但是在我的情况下这是不实际的(从开发的角度来看),因为我打算在不同的情况下创建许多不同的子类文件,也许是由不同的人制作的,我不想每次调整/维护基类,添加虚拟方法!

怎么做?基本上,我要问的是(我猜)是如何实现像Objective-C NSArrays这样的东西 - 如果你向一个没有实现该方法的对象发送消息,那么,没有任何反应。

问候

3 个答案:

答案 0 :(得分:1)

您可以执行您在C ++中描述的内容,但不能使用函数。顺便说一下,它有点可怕,但我认为可能是合法的方法。

这样做的第一种方式:

使用类似boost::variant parseMessage(std::string, std::vector<boost::variant>);的签名定义一个函数,并且可能是基类上具有公共签名的一系列便捷函数,并在基类上包含一个带有仿函数的消息查找表。在每个类构造函数中,将其消息添加到消息表中,然后parseMessage函数将每个消息包装到类的右侧函数中。

它很丑陋而且很慢但它应该有效。

第二种方式:

在层次结构的下方定义虚函数,因此如果要添加int foo(bar*);,首先要添加一个将其定义为虚拟的类,然后确保每个想要定义int foo(bar*);的类继承它。然后,您可以使用dynamic_cast确保您正在查看的指针在尝试调用int foo(bar*);之前从此类继承。可能这些接口添加类可以是纯虚拟的,因此可以使用多重继承将它们混合到各个点,但这可能有其自身的问题。

这不如第一种方式灵活,并且要求实现函数的类相互链接。哦,它仍然很难看。

但大多数情况下,我建议您尝试编写C ++代码,如C ++代码而不是Objective-C代码。

答案 1 :(得分:1)

这可以通过添加某种内省功能和元对象系统来解决。这个讲话Metadata and reflection in C++ — Jeff Tucker演示了如何使用c ++的模板元编程来做到这一点。

如果您不想自己解决问题,那么使用现有的Qt meta object system会更容易。请注意,由于元对象编译器中的限制,此解决方案不适用于多重继承:QObject Multiple Inheritance

安装完成后,您可以查询方法的存在并调用它们。手动操作非常繁琐,因此调用此类方法的最简单方法是使用signal and slot机制。

还有GObject非常相似,还有其他人。

答案 2 :(得分:0)

如果您是planning to create many different children classes in different files, perhaps made by different people,我猜您也不想更改每个子课程的主要代码。然后我认为你在基类中需要做的是定义几个(不是很多)虚函数(使用空实现)但是这些函数应该用于在逻辑中标记它们被称为“AfterInseart”的时间或“BeforeSorting”,等等 通常,逻辑中没有很多地方可以让派生类执行自己的逻辑。