【问题标题】:Accessing derived class methods from base class method or another suggestion从基类方法或其他建议访问派生类方法
【发布时间】:2020-04-19 10:26:44
【问题描述】:

考虑下面的代码(我知道你可能认为这是一个奇怪的设计。我愿意接受建设性的建议):

class Graphics
{
    // ...

public:
    template <typename Type, typename... Types>
    void draw(Type const& object, Types const&... objects)
    {
        // ...
        addToBatch(object, objects...);
        // ...
    }

protected:
    void addToBatch(Type const& object, Types const&... objects)
    {
        _addToBatch(object);
        if constexpr (sizeof...(objects) > 0)
            addToBatch(objects...);
    }

    void _addToBatch(Rect rc, Brush b);
    void _addToBatch(std::pair<Rect, Brush> rcAndBrush)
    {
        _addToBatch(rcAndBrush.first, rcAndBrush.second);
    }
    void _addToBatch(TextLayout const& tl, Brush b, Point origin);
    // ... etc
}


class SpecializedGraphics : public Graphics
{
    // ...

protected:
    // here I want to implement methods for specialized complex processing,
    // which will use _addToBatch methods from base class
    void _addToBatch(Entry const& e);
    void _addToBatch(Menu const& menu);
    // etc
}

int main()
{
    Rect rcClient;
    Brush brush;
    Entry e;
    Menu menu;
    // etc

    SpecializedGraphics gfx;
    gfx.draw(
        std::make_pair(rcClient, brush),
        e,
        menu,
        // etc
    )
    return 0;
}

这段代码给了我一个编译器错误。我想这是因为 Graphics::draw 是基类方法,无法访问派生类的方法。如何正确解决此问题?我想到的一种解决方案是将draw方法的定义从基类复制/粘贴到派生类(名称隐藏)。有更好的建议吗?因为为什么我需要定义已经定义的内容。

【问题讨论】:

  • 使用virtual函数
  • 这意味着我必须在基类中声明一个具有已知签名的虚拟方法。但是为什么一般图形甚至应该知道所有这些复杂性呢?
  • 基类应该如何调用它不知道的函数?基类并不知道从它继承的每一个类(如果它实际上不是具有这些功能的类,它会做什么?)
  • @UnholySheep 你可以通过在基类中使用纯虚函数来做到这一点。
  • @SeventhSon84 这正是我的建议。但这仍然意味着基类必须“知道”这些虚函数的存在

标签: c++ inheritance overriding overloading variadic-templates


【解决方案1】:

你可以使用纯虚函数, 在您的基类中更改您想要将实现保留为派生类的方法声明,如下所示:

virtual void _addToBatch(Rect rc, Brush b) = 0;

通过这样做,该方法现在被声明为纯虚拟,

现在您必须在您的 Specialized 类中定义这些函数:

class SpecializedGraphics : public Graphics
{
 protected:
  void _addToBatch(Rect rc, Brush b);

【讨论】:

  • 正如我在 cmets 中所说的,我不认为通用图形应该知道专用图形的所有这些复杂性。也许一般的绘图功能可以标记为虚拟并在专用图形中重新实现,尽管它会完全相同。
  • 但是,很遗憾,我无法制作虚拟模板功能。好吧,我只剩下愚蠢的复制/粘贴了。
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 2012-09-16
  • 2017-11-28
相关资源
最近更新 更多