c++ - 插件代码中的公共(public)基类

标签 c++ c++11

该应用程序定义了 3 个要在插件中实现的接口(interface)。 Widget 始终是基础。

// Application code...
class Widget {
    virtual void animate() = 0;
};

class BigWidget : public Widget {
};

class SmallWidget : public Widget {
};

每个接口(interface)的实现都源自NiceWidget,它提供了一些插件内部通用信息。

// Plug-in code...
class NiceWidget {
    // nice::Thing is only known in plug-in code.
    nice::Thing thing();
};

class NiceBigWidget : public NiceWidget, public BigWidget {
    void animate() override;
};

class NiceSmallWidget : public NiceWidget, public SmallWidget {
    void animate() override;
};

func 从应用程序代码中调用。 wid 已知是由该插件实现的。因此 wid 也是一个 NiceWidgetfunc 的目标是调用它的 thing 方法。

// Plugin-in code...
void func(Widget* wid) {
    // wid is either NiceBigWidget or NiceSmallWidget.
    auto castedBig = dynamic_cast<NiceBigWidget*>(wid);
    if (castedBig) {
        castedBig->thing().foo();
        return;
    }

    auto castedSmall = dynamic_cast<NiceSmallWidget*>(wid);
    if (castedSmall) {
        castedSmall->thing().foo();
        return;
    }

    assert(false);
}

但是,随着层次结构大小的增加,尝试将 wid 转换为每个 Nice* 可能会变得非常糟糕。有更好的解决方案吗?

最佳答案

首先:如果您知道 wid 始终是 NiceWidget*,为什么不在 func() 中这么说呢?而且你根本不需要类型转换:

void func(NiceWidget* wid)
{
  wid->thing().foo();  // Done
}

即使您出于某种原因无法更改函数签名,您也只需要一次强制转换:

void func(Widget* wid)
{
  NiceWidget* casted = dynamic_cast<NiceWidget*>(wid);
  if (casted)
    casted->thing().foo();
  else
    throw std::exception(); // Well, throw the right exception
}

当然,如果您认为这更适合您的目的,您可以 assert() 而不是抛出异常。

无论如何,您只需要一个指向定义需要使用的函数的类(在本例中为 thing())的指针,而不是指向最派生类的指针。如果您要重写派生类中的函数,请将其设为虚拟,这样就完成了。

关于c++ - 插件代码中的公共(public)基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14143002/

相关文章:

c++ - 我可以使用哪个 STL 容器/算法来解决这个问题?

c++ - 指向成员变量和模板

c++ - 为什么我在 Qt 中继承 QWidget 类时会发生内存泄漏

c++ - Windows 函数 ChoosePixelFormat 在 Windows 7 上返回 ERR_OLD_WIN_VERSION

c++ - 需要 : A popup window without a taskbar icon

c++ - 在C++中递归地从十进制到八进制。以std::string格式输出

c++ - 在不使用 boost::any 的情况下将参数存储在可变参数模板函数中

c++ - 使用可变模板参数传递成员函数指针是不明确的

c++ - g++ 4.4.7 -std=gnu++0x 应该编译 "for each"构造吗?

c++ - 将指针转换为二维数组