Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Разница между override и virtual [дубликат]

#cpp #ооп


        
             
                
                    
                        
                            This question already has answers here:
                            
                        
                    
                
                        
                            virtual и override
                                
                                    (5 ответов)
                                
                        
                                Closed 3 года назад.
            
                    
Многие примеры на сайтах показывают использование virtual в объявлении класса, но
в дочерних нет никакого override. На msdn.microsoft.com же наоборот пихают virtual
также и дочернему классу, + override. 

Хотелось бы узнать, вот если я вызываю из базового класса метод 

void Base::Method() {

},


Который не переопределяется, а в этом методе используются методы, которые переопределены
в дочерних классах - они будут переопределены автоматически или только в случае (Son
*) (ptr)->Method2()? И как будет выглядеть ситуация в обоих случаях если virtual void
Base::Method2() = 0;?



Вопрос из ответа участника @ Artem.
    


Ответы

Ответ 1



virtual указывает, что дочерний класс может переопределить метод. Это совсем не означает, что в дочернем классе будет override. Он может быть. На msdn.microsoft.com же наоборот пихают virtual также и дочернему классу, + override. К дочернем классам добавляют virtual к методу, чтобы указать, что его потомки так же могут переопределить метод. Про вторую часть вопроса: class Base{ void Method() { bar(); } virtual void bar(); { } }; class A : public Base { virtual void bar() { } }; class B : public A { virtual void bar() { // do something } }; Сделав так: A* myObject = new B(); myObject->Method(); Вызовется метод из класса B. Собственно, возвращаясь к virtual. Я мог в классах A и B не объявлять методы как virtual, всё равно сработает метод из B. Точно так же, независимо от того, напишу я так virtual void bar() в B классе или так virtual void bar() override, тоже ничего не изменится. Что с override, что без него метод дочернего класса перекроет метод базового. Просто написав override мы явно это указываем. Очень полезно, если вы с кодом работаете не один.

Ответ 2



Когда мы объявляем функцию виртуальной, используя virtual, то это равносильно тому, как если бы мы обращались к ней не напрямую, а через указатель. typedef void (*functionPointer)(ClassA*); struct ClassA { functionPointer func1; bool called; }; void callMe(ClassA* thisA) { thisA->called = true; } ClassA ca; ca.called = false; ca.func1 = callMe; ca.func1(&ca); // Будет вызвана функция callMe(). Поэтому при обращении к перекрытому методу всегда будет вызвана именно "последняя" версия функции. Даже если обращаться к ней, указывая класс-предок. C помощью override можно избежать случайного поведения наследования в коде.В следующем примере показано, в какой ситуации без использования override поведение функции-члена производного класса может быть случайным. Компилятор не выдает ошибки при использовании этого кода. class BaseClass { virtual void funcA(); virtual void funcB() const; virtual void funcC(int = 0); void funcD(); }; class DerivedClass: public BaseClass { virtual void funcA(); // ok, работает как подразумевается virtual void funcB(); // DerivedClass::funcB() не const, так что он не перекрывает // BaseClass::funcB() const и является новым методом virtual void funcC(double = 0.0); // DerivedClass::funcC(double) имеет другой // тип параметра, чем BaseClass::funcC(int), так что // DerivedClass::funcC(double) тоже новый метод }; Подробнее можно прочитать здесь.

Комментариев нет:

Отправить комментарий