Как перебирать базовые объекты, являющиеся определенным производным классом

0

Допустим, я реализовал следующие классы

class A
{
   public:
      virtual void printA() 
      { 
         cout << "Hi from A!" << endl; 
      }
};

class B : public A
{  
   public:
      virtual void printB() 
      { 
         cout << "Hi from B!" << endl; 
      }
};

class C : public B
{
   public:
      void printC() 
      { 
         cout << "Hi from C!" << endl; 
      }
};

Позволяет также сказать, что я создал std::vector<A *> vec который содержит случайное количество объектов, созданных из A, B и C. Теперь можно сказать, что я вынужден перебирать все объекты в vec но только объекты вызова, которые имеют метод printC() (т.е. экземпляры C). Каков наилучший способ сделать это?

int main()
{
    std::vector<A *> vec;

    ....
    // insert random objects from both A, B and C into vec
    ....

    for(vector<A *>::iterator x = vec.begin();
        x != vec.end();
        x++)
    {
       if(dynamic_cast<C *>(*x) != 0)   // 1. is this OK?
         (*x)->printC();
       else
         (*x)->printA();                // 2. is this also OK?

    }
}
  1. 1 Хорошо? И если это наилучшая практика?

  2. Также возникнут проблемы 2 в случае экземпляров C?

Возможно, это глупые вопросы, но Im, совершенно новый для C++, и то, как полиморфизм работает в C++, очень странно для меня. благодаря

  • 0
    Что i , я не вижу, это определено.
  • 0
    Это не скомпилируется. Потому что printC() не является функцией-членом A Приведи лучший пример
Показать ещё 2 комментария
Теги:

2 ответа

2
Лучший ответ

1 не будет работать, так как *x имеет тип A*, а A не имеет члена printC. Должен быть:

if (C * c = dynamic_cast<C *>(*x)) {
    c->printC();
}

2 отлично, но не соответствует вашему описанию; вы говорите, что хотите "только вызывать объекты с printC() ", в то время как это вызывает printA() для других объектов.

Однако это похоже на нечетный дизайн; вы обычно определяете одну виртуальную функцию, реализованную каждым классом для правильной работы для этого класса, а затем вызываете это безоговорочно для всего.

3

Я думаю, вы имеете в виду следующее

#include <iostream>
#include <vector>


int main() 
{
    class A
    {
    public: 
        virtual ~A() = default;
        virtual void print() const 
        { 
            std::cout << "Hi from A!" << std::endl; 
        }
    };

    class B : public A
    {  
    public: 
        void print() const
        { 
            std::cout << "Hi from B!" << std::endl;
        }
    };

    class C : public B
    {
    public:
        void print() const 
        { 
            std::cout << "Hi from C!" << std::endl; 
        }
    };

    std::vector<A *> v = { new A(), new B(), new C() };

    for ( A *p : v ) p->print();

    return 0;
}

Выход

Hi from A!
Hi from B!
Hi from C!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню