【问题标题】:C++ Inheritance Question edit: more troublesC++继承问题编辑:更多麻烦
【发布时间】:2010-06-04 03:58:55
【问题描述】:

我有一个基类 MessageHandler 和 2 个派生类 MessageHandler_CB 和 MessageHandler_DQ。

派生类重新定义了 handleMessage(...) 方法。 MH_DQ 处理消息并将结果放入双端队列,而 MH_CB 处理消息然后执行回调函数。

基类有一个静态回调函数,我将它与 this 指针一起传递给一个库,当有新消息可用于处理时,该库调用静态回调。

当我在静态回调中使用 void * 指向 MH_DQ 或 MH_CB 时,我的问题就出现了。如果我将它转换为基类,则会调用空 MessageHandler::handleMessage(...) 方法,而不是相应派生类中的版本。

从设计角度解决这种情况的最佳方法是什么和/或哪些语言功能可以帮助我实现问题的解决方案?

提前致谢!

好吧,虚拟方法并没有像魔术一样工作。故事有一个转折点。我在基类中有一个静态方法和一个纯虚成员函数来处理消息,但是我想在将消息路由到派生类之前先调用纯虚基类中的成员函数来预处理消息。

所以我有:

class MH {

...

static int CallBackFunction(MessageData *md, void *this_ptr) {
  ((MH *)this_ptr)->preprocess(md);
  return 1;
}

virtual int preprocess(MessageData *md) {
  // do some stuff
  . . .

  handleMessage(md);
  return 1;
}

virtual void handleMessage(MessageData *) = 0;

};

class MH_CB : public MH {

...

void handleMessage(MessageData *md) {
  // do something
  ...
}
};

class MH_DQ : public MH {
...

void handleMessage(MessageData *md) {
  // do something different
  ...
}
};

不幸的是,这段代码会产生一个运行时错误,表明正在调用纯虚函数。有什么想法吗?

TIA

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    将原始方法调用设为虚拟。

    【讨论】:

      【解决方案2】:

      不要在回调中传递 void* - 传递一个指向基类的指针,并将 handleMessage 声明为虚拟。

      【讨论】:

        【解决方案3】:

        virtual关键字添加到基类中方法的声明/定义中。

        事实上,如果基类中的方法永远不应该运行,那么您可以指定它是pure virtual 来声明它根本没有主体,而不是定义一个空主体:

        class MessageHandler
        {
        public:
            virtual void handleMessage(...) = 0;
        };
        

        【讨论】:

          【解决方案4】:

          通过在void handleMessage() 或基类中的任何声明前加上单词virtual 将handleMessage() 标记为虚拟。然后,确保派生类实现完全相同的消息签名(即相同的返回类型和参数类型)。

          另外,使用 MessageHandlerBase*(或任何合适的)代替 void*。那你就不需要投了。强制转换通常是程序员出现逻辑错误的标志。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-28
            • 1970-01-01
            相关资源
            最近更新 更多