首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >插件代码中的公共基类

插件代码中的公共基类
EN

Stack Overflow用户
提问于 2013-01-04 00:29:42
回答 2查看 184关注 0票数 2

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

代码语言:javascript
运行
复制
// Application code...
class Widget {
    virtual void animate() = 0;
};

class BigWidget : public Widget {
};

class SmallWidget : public Widget {
};

每个接口实现都是从NiceWidget派生的,它提供了一些插件内部公共信息。

代码语言:javascript
运行
复制
// 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方法。

代码语言:javascript
运行
复制
// 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*可能会变得非常糟糕。有没有更好的解决方案?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-04 00:41:36

首先:如果你知道wid永远是一个NiceWidget*,为什么不在func()中这么说呢?而且你根本不需要造型:

代码语言:javascript
运行
复制
void func(NiceWidget* wid)
{
  wid->thing().foo();  // Done
}

即使你因为某种原因不能改变函数签名,你也只需要进行一次转换:

代码语言:javascript
运行
复制
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()),而不是指向最多的派生类。如果要重写派生类中的函数,请将其设为虚拟的,这样就完成了。

票数 3
EN

Stack Overflow用户

发布于 2013-01-04 00:42:15

如果您知道每个NiceWidget都是Widget,那么您应该考虑从Widget扩展NiceWidget

代码语言:javascript
运行
复制
class Widget {
    virtual void animate() = 0;
};

class BigWidget : public Widget {
};

class SmallWidget : public Widget {
};

class NiceWidget : Widget{
    // 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;
};

还会有另一个称为The diamond problem的问题,它可以使用虚拟扩展来解决

之后,从WidgetNiceWidgetdynamic_cast应该是可以的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14143002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档