В C ++, когда мы делаем функцию чисто виртуальной в базовом классе, тогда зачем снова делать ту же функцию виртуальной в дочернем классе? - PullRequest
0 голосов
/ 26 марта 2012

У меня есть функция X (), объявленная как PURE VIRTUAL в базовом классе:

class Base 
{
public:  
    virtual HRESULT X()=0; // Now it's pure virtual. 
    .......
    };




class Derived_1 : public Base  
  {   
    HRESULT X()   
    {  
    // body of function X() ; full definition given here as per Derived_1's context. SHOULD WE MAKE THIS VIRTUAL?                                                     
    }

    ..................              

  };            

class Derived_2 :public Base             
   {          
    HRESULT X()            
         {             
        // body of function X() ; full definition given here Derived_2's context.  SHOULD WE MAKE THIS VIRTUAL?
        }              
         ..................           
   };

Если наше намерение состоит в том, чтобы вызывать функцию X () в общем случае с использованием указателя базового класса, чтобы было принято решение о том, будет ли определено определение X () в Derived_1 или Derived_2, то необходимо ли сделать X () в производных классах Virtual тоже.

Base * bPtr;
bPtr = new Derived_1(); OR bPtr = new Derived_2(); (Dynamic decision)
bPtr->X()

Мне кажется, нет необходимости прикреплять виртуальное ключевое слово к определению в производных классах. Я прав?

Заранее спасибо.

Ответы [ 5 ]

3 голосов
/ 26 марта 2012

C ++ имеет правило об этом: один раз виртуальный, всегда виртуальный.Если вы говорите «виртуальный» в производных классах, это не меняет того факта, что X() будет виртуальным.Вы можете сказать это или нет;В любом случае X() будет виртуальным в производных классах.

3 голосов
/ 26 марта 2012

Функции в производных классах автоматически становятся виртуальными, если сигнатура функции (тип аргументов и возвращаемое значение, идентификаторы, такие как const и virtual) в производном классе идентична той, которая находится в вашем базовом классе. Неважно, виртуальный он или виртуальный.

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

2 голосов
/ 26 марта 2012

Технически не нужно писать virtual.

Практически это документирует, что функция virtual: это означает, что при наследовании мне не нужно проверять весь путь до базового класса, чтобы увидеть, действительно ли это virtual функция. Это также подчеркивает обычные предостережения: то есть вызов конструктора или деструктора на ваш страх и риск.

В C ++ 11 есть лучшая альтернатива документу "унаследованная виртуальность", ключевое слово override.

class Base { public: virtual void method() = 0; };

class Derived: public Base { public: void method() override; };

Ключевое слово override означает, что сообщение должно переопределить метод базового класса (здесь базовый является транзитивным). Если метод базового класса не переопределен, код ошибочен, и компилятор выдаст ошибку.

Следовательно, наличие override фактически делает разницу между base методом (сначала определяющим новый виртуальный метод в классе) и переопределяющим методом. И это статически проверяется компилятором.

2 голосов
/ 26 марта 2012

Функция, объявленная виртуальной в базовом классе, является виртуальной в производном классе, если она имеет тот же прототип и явно не объявлена ​​виртуальной.

Вам не нужно добавлять виртуальную функцию в функцию производного класса.

Ссылка: C ++ 03 10.3 Виртуальные функции Пункт 3

[Примечание: функция виртуального члена не должна быть видимой, чтобы быть переопределенной, дляНапример,

struct B {
    virtual void f();
};
struct D : B {
    void f(int);
};
struct D2 : D {
    void f();
};

functionf(int) в classD скрывает виртуальный functionf() в своей базе classB; D::f(int) не является виртуальной функцией. Однако, f(), объявленный в classD2, имеет то же имя и тот же список параметров, что и B::f(), и, следовательно, является виртуальной функцией, которая переопределяет функцию B::f(), даже если B::f() не являетсявидимый в classD2.]

2 голосов
/ 26 марта 2012

После того, как функция объявлена ​​виртуальной в базовом классе, не требуется объявлять виртуальную в производном классе. Иногда люди объявляют виртуальное в производном классе, потому что они чувствуют, что это более понятно, но это не является обязательным требованием.

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