Существует ли шаблон проектирования для достижения полиморфизма во время выполнения без использования динамического приведения c для этого сценария? - PullRequest
0 голосов
/ 14 апреля 2020

Допустим, у меня есть структура класса, в которой родительский класс P хранит вектор указателей на дочерние объекты класса C.

class P {
public:

    P() {}

private:
    std:: vector<C*> children;
};

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

class C
{
public:
    C() {}

    virtual ~C() {}
    virtual void initialize() = 0;
};

class D : public C {
public:
    void initialize() override;

    //Member variable unique to D
    int value;
};

class E: public C {
public:
    void initialize() override;

    //Member variable unique to E
    std::vector<int> vector_value;
};

Во время выполнения объекты C и D создаются и добавляются в вектор потомков родительского P.

Позже раз я хочу перебрать этот вектор, определить тип объекта и использовать уникальную дочернюю переменную-член.

Я знаю, что могу добиться этого с помощью динамического c cast:

for( C* child : children)
{
   D* d_child = dynamic_cast<D*>(child);
   if( d_child != nullptr)
   {
      // This object is of type D 
      do something with  d_child->value ...
   }
   else
   {
      // This object is of type E
       do something with  d_child->vector_value...
   }
}

Однако, это плохой дизайн, когда нам приходится проверять типы, повторяемые здесь многими ответами Проверка на производный тип (C ++)

Итак, я хочу знать, существует ли стандартный способ или шаблон проектирования, который поможет мне улучшить эту функцию?

1 Ответ

1 голос
/ 14 апреля 2020

Вы можете добавить виртуальный метод в ваш базовый класс:

class C
{
public:
    virtual ~C() {}
    virtual void print() = 0;
    virtual void initialize() = 0; // That one is strange,
                                   // cannot you move initialization in constructor instead?
};

class D : public C {
public:
    void initialize() override;
    void print() override { std::cout << value; }

    //Member variable unique to D
    int value;
};

class E: public C {
public:
    void initialize() override;
    void print() override { for (auto value : vector_value) std::cout << value; }

    //Member variable unique to E
    std::vector<int> vector_value;
};

Если вы начнете добавлять слишком много методов в базовый класс, тогда Шаблон посетителя может стравить зависимости. Требуется знать каждый тип детей, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...