扩展一个没有源重新编译的抽象基类?

时间:2009-02-27 23:22:47

标签: c++

忽略这一点,我想到了涉及标题生成的解决方法。它不是最好的解决方案,但它的工作原理。这个问题很难理解。基本上我想调用一个尚未在lib或dll中声明的虚函数并正常使用它(但它没有实现/空func)。

我的库中有一个抽象基类。我的所有插件都继承自它,用户插件继承自这个类,他的应用程序使用这个类作为插件指针。我希望该用户能够扩展该类并添加其功能。问题是,我确信如果他添加了一个虚函数并尝试调用它,代码将因为我的对象在其vtable中没有额外数据而崩溃。我该如何解决这个问题?我想继承它,但当第三个用户上场时,这会导致丑陋的问题。我不希望他转发类型来发送扩展功能。

我在想一个像intptr_t sendMsg这样的msg函数(enum msgName,void * argv);但这取消了安全性,我需要对所有内容进行类型转换。什么是最好的解决方案?我宁愿使用vtables然后使用sendMsg函数。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我认为你可以使用注册和回调机制

您的插件可以提供 抽象基类“基”和函数

Register(Base *);

现在客户端可以调用插件注册函数

Register(b);

其中b定义为

Base *b = new Derived;

其中Derived是从Base

派生的新类

答案 1 :(得分:1)

您是否询问是否可以在不重新编译的情况下将虚拟功能添加到 base 类?对此的简短回答是“不”。答案很长就在你的问题中,你必须提供某种通用的“call_func”接口,它允许你“动态地”调用函数。

答案 2 :(得分:1)

我不是百分百肯定我看到了问题 如果user1派生类型扩展了你的基类(使用更多虚拟方法)那么这应该没问题(当然你的代码永远不会知道或理解这些新方法,但可能你不会调用它们:

class B
{
    virtual void doStuff() { /* Nothing */}
};

// User 1 version:
class U1: public B
{
     virtual void doStuff()
     {
         this->doA();
         this->doB();
     }
     virtual void doA()  {}
     virtual void doB()  {}
};

// User 2 version can extend it differently.

注意:
如果你担心切片,因为你将对象存储在一个稍有不同的向量中。

std::vector<B>   objs;
objs.push_back(U1());

std::for_each(objs.begin(),objs.end(),std::mem_fun_ref(&B::doStuff));

这里的问题是用户定义的类型U1无法复制到向量中,因为向量只保存B对象。这会切掉U1中保存的额外数据。

这个问题的解决方案是你需要在向量中保存指针。这当然会导致异常安全的其他问题。所以boost有ptr_vector&lt;&gt;容器可以正确保存对象,但仍然可以像对象一样使用它们。

 #include <boost/ptr_container/ptr_vector.hpp>

 ......

boost::ptr_vector<B>   objs;
objs.push_back(new U1());

std::for_each(objs.begin(),objs.end(),std::mem_fun_ref(&B::doStuff));