Добавление метода в производный класс и вызов его из базового указателя

Допустим, у меня есть следующая иерархия классов:

class A
{
public:
    virtual ~A();
};

class B : public A
{};

class AUser
{
public:
    virtual ~AUser();
protected:
    A* m_pA;
};

class BUser : public AUser
{};

Теперь я хочу добавить метод B который не имеет отношения к A и будет вызываться только из BUser,

class B : public A
{
public:
    void addedFunctionality()
    {
        // do something
    }
};

Для вызова добавленного метода у меня есть два варианта:

  1. Добавьте пустой метод к A:

    class A
    {
    public:
        virtual ~A();
        void addedFunctionality()
        {
            // do nothing
        }
    };
    
    class BUser : public AUser
    {
        void useB()
        {
            m_pA->addedFunctionality();
        }
    };
    
  2. вызовите добавленный метод, используя downcast:

    class BUser : public AUser
    {
        void useB()
        {
            static_cast<B*>(m_pA)->addedFunctionality();
        }
    };
    

Я знаю, что следует избегать падений, но мне не нравится первый вариант, так как он раздут AКод без причины.

Есть ли другая альтернатива дизайна?

1 ответ

Решение

Самое простое решение выглядит так (также предложено Ulrich Eckhardt):

class AUser
{
public:
    AUser(A* a)
    {
      m_pA = a;
    }
protected:
    A* m_pA;
};

class BUser : public AUser
{
public:
    BUser(B* b) : AUser(b)
    {
      m_pB = b;
    }

    void useB()
    {
        m_pB->addedFunctionality();
    }
protected:
    B* m_pB;
};

Менее чистый, но вы также можете рассмотреть это:

class BUser : public AUser
{
public:
    BUser(B* b) : AUser(b)
    {
    }
    void useB()
    {
        getB()->addedFunctionality();
    }
protected:
    B *getB()
    {
      return dynamic_cast<B*>(m_pA);
    }

};
Другие вопросы по тегам