2016-04-17 2 views
1

Я немного новичок в программировании на языке C++ и нуждаюсь в небольшой помощи.C++ метод вызова из подкласса в суперклассе

Предположим, у меня есть класс Animal и подкласс cat. В основной программе я сделал массив указателей на животное, как это:

Animal* array[10]; 
array[0] = new Cat(); 

Подкласса кот имеет свое собственное число, и метод GetType вернуть это целое число. Я хотел бы знать, как я могу назвать этот метод.

Я пробовал:

array[0]->getType() 

Но он говорит, что метод не может быть решен, и этот класс животных не имеет ни одного члена с именем GetType. Я также попытался сделать этот метод виртуальным и все еще не работал. Любые решения?

С уважением

ответ

-2

Для того, чтобы позвонить по телефону getType(), необходимо позвонить Cat *. В C++ указатели преобразуются (литые) с использованием casting operators.


Если вы уверены (это может укусить вас обратно в больших программах), что ваш array[0] действительно указывает на объект класса Cat, вы можете использовать (см ideone для полной программе)

Cat * catPtr = static_cast<Cat *>(array[0]); 
catPtr->getType(); 

или сжато,

static_cast<Cat *>(array[0])->getType(); 

Обратите внимание, что это не ужасно, если array[0] не указатель на Cat.


До тех пор, пока ваши классы являются полиморфными (содержит виртуальные элементы), которые, в вашем случае (массив указателей базового класса и запущенное производные методы), вероятно, следует так, то вы можете использовать dynamic_cast вместо static_cast. Это налагает на служебные данные во время выполнения, но проверяет правильность преобразования и возвращает nullptr, если это не так.

+0

Спасибо, что отлично работает в моем случае! – timcheee

+0

@timcheee Обратите внимание, что, хотя это работает, писать код таким образом является плохой практикой (поэтому мой ответ был опущен). Попробуйте подходы в ответах других людей. –

+0

Прежде чем я сделаю это предложение, я проверяю инструкцию IF, если массив [i] является указателем на Cat, поэтому я уверен, что я не преобразовываю другие подклассы в Cat – timcheee

-1

Если я правильно помню вы должны привести массив [0] в качестве типа Cat. Так было бы, как этот

dynamic_cast<Cat>(array[0])->getType(); 

Это мой первый пост, и я не пробовал мое предложение, поэтому я прошу прощения, если это не так.

1

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

virtual void getType() { cout << "Animal" << '\n'; } 

И в производном классе вы можете переопределить его:

void getType() override { cout << "Cat" << '\n'; } 

Теперь вы можете вызвать array[0]->getType() и он будет использовать переопределенное Cat::getType()

+0

Это на самом деле лучший ответ, чем мой. Однако добавление тел 'getType()' было бы неплохо. –

0

Кажется, вы хотите иметь несколько подклассов Animal, которые будут иметь те же методы и что вы будете использовать массив из Animal * для вызова методов подклассов. Если это так, то вы должны сделать Animal методы класса virtual:

  1. декларировать все методы (которые вы хотите, чтобы все ваши подклассы иметь) в Animal класса
  2. Если у них есть реализация «по умолчанию», положить, что в Animal
  3. в противном случае, сделать их чисто виртуальными в Animal (пример)
  4. в подклассы, переопределяют чисто виртуальные методы, плюс те, которые будут иметь не по умолчанию реализация

Так что ваш Animal класс должен выглядеть следующим образом:

class Animal { 
    public: 
     virtual int getType() = 0; // purely virtual function 
}; 

и ваш Cat класс должен переопределить методы (отмечают, что override идентификатор не является необходимым, хотя рекомендуется)

class Cat : public Animal { 
    public: 
     int getType() override { 
      return 42; 
     } 
}; 

Этот позволяет иметь

Animal * array[10]; 
array[0] = new Cat(); 
std::cout << array[0]->getType() << std::endl; 

, который будет печатать 42. См. ideone example.

Смежные вопросы