2015-11-09 3 views
0

Я не знал, что дать в качестве названия, я ожидаю, что более опытные пользователи stackoverflow.com смогут его улучшить.Вызов метода подкласса из указателя базового класса?

Допустим, мы имеем класса А

class A { 
    void hello(){ cout << "i'm an A" << endl; } 
} 

и его подклассу B

class B: public A { 
    void hello(){ cout << "i'm a B" << endl; } 
} 

Тогда мы сделали где-то в нашей программе

A* array[2]; 
array[0] = new A; 
array[1] = new B; 
array[0]->hello(); // output: "i'm an A" 
array[1]->hello(); // output: "i'm a B" 

почему не array[1].hello(); output I'm a B, поскольку мы создали объект B для этого базового класса po inter? и как это сделать?

+1

Потому что вы не объявили его виртуальным. –

+0

См. Http://stackoverflow.com/questions/5854581/polymorphism-in-c – sehe

+0

[Нет виртуального, без переопределения.] (Http://en.cppreference.com/w/cpp/language/virtual) C++ по умолчанию наименьшая, максимально возможная интерпретация. Если вам нужны фантазии, вы должны это сказать. – user4581301

ответ

2

Пара изменений здесь:

делают функцию привет в классе А, virtual и public:, потому что по умолчанию это private

class A { 
public: 
virtual void hello(){ cout << "i'm an A" << endl; } 
}; 

Аналогично сделать привет в классе Bvirtual

class B: public A { 
virtual void hello(){ cout << "i'm a B" << endl; } 
}; 
1

Вы должны сделать hello виртуальную функцию:

class A { 
    virtual void hello() { cout << "i'm an A" << endl; } 
}; 

class B : public A { 
    virtual void hello() override { cout << "i'm a B" << endl; } // 1) 
}; 

Это говорит компилятору, что фактическая функция не должна быть определена с помощью статического типа (типа указателя или ссылки), но в динамике (время выполнения).

1) Ключевое слово override сообщает компилятору проверить, действительно ли функция переопределяет функцию hello в базовом классе (помогает, например, улавливать орфографические ошибки или различия в типах параметров).

+0

Вижу, я ошибся, я всегда думал, что 'virtual' является ключевым словом C++ для' абстрактных' методов. Теперь я получил правильное представление об этом –

+0

@reaffer: Вы были частично правы: абстрактные методы имеют смысл, если они виртуальны. Таким образом, вы всегда найдете ключевое слово abstract перед объявлением абстрактного метода. Чтобы сообщить компилятору, что метод является не только виртуальным, но и абстрактным в C++, следует добавить '= 0' после его объявления. – MikeMB

0

Поскольку вы унаследовали класс A в классе B, производный cl зад B будет вызывать функцию из базового класса. Вам необходимо переопределить функцию в классе B, так как вы хотите изменить функциональность базового класса.

Вы можете сделать это с помощью переопределения и виртуальных ключевых слов.

http://en.cppreference.com/w/cpp/language/override

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