Доступ к методам производного класса из метода базового класса или другого предложения - PullRequest
0 голосов
/ 19 апреля 2020

Рассмотрим следующий код (я знаю, что вы можете подумать, что это странный дизайн. Я открыт для конструктивных предложений):

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 из базового класса в производный класс (скрытие имени). Есть лучшие предложения? Потому что зачем мне определять то, что уже определено.

1 Ответ

0 голосов
/ 19 апреля 2020

Вы можете использовать чисто виртуальные функции, в вашем базовом классе измените объявление методов, которые вы хотите оставить реализациям, для производных классов, например:

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

, сделав так, что метод теперь объявлен как чисто виртуальный ,

внутри ваших специализированных классов теперь вы должны определить эти функции:

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