Реализация виртуальных функций C ++ вне класса - PullRequest
8 голосов
/ 21 декабря 2010

Я новичок в C ++.Пробуя пример кода полиморфизма, я обнаружил, что определение виртуальной функции базового класса в производном классе возможно только в том случае, если оно определено в производном классе или вне его с объявлением в производном классе.

Следующий код дает ошибку:

class B
{
public:
    virtual void f();
};

void B::f() {
    std::cout<<"B::f";
}

class D : public B
{
public:
    void f2() {int b;}
};

// error: no "void D::f()" member function declared in class "D"
void D::f() {
    std::cout<<"D::F";
}

Это работает, если я объявляю f () внутри D. Мне было интересно, почему мне нужно снова явно объявить функцию, когда она уже объявлена ​​вБазовый класс.Компилятор может получить подпись из базового класса, верно?

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

Ответы [ 4 ]

9 голосов
/ 21 декабря 2010

Вы не можете добавлять членов в класс вне определения класса. Если вы хотите, чтобы D имел переопределение для B::f, вы должны объявить его внутри определения класса. Это правила.

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

3 голосов
/ 21 декабря 2010

Даже если D наследуется от B и, следовательно, вы можете вызвать f () для экземпляра D, это не значит, что вам не нужно помещать объявление в заголовок.

Любая реализуемая вами функция должна быть явно объявлена ​​в заголовке.

Однако вам не нужно помещать его реализацию там. Just

class D : public B
{
public:
   /*virtual*/ void f();
};

и вы можете выбрать, включать ли слово «виртуальный» здесь

1 голос
/ 21 декабря 2010

В C ++ ваше определение класса сообщает компилятору, какие функции реализует класс. Поэтому, если вы хотите написать функцию «D :: f ()», вы должны иметь f () в определении класса для D.

Тот факт, что функция "B :: f ()" была определена в базовом классе, не имеет значения. Каждое определение класса должно явно объявлять функции, которые оно реализует.

0 голосов
/ 26 февраля 2019

Измените код для класса D, как показано ниже, и попробуйте:

class D : public B
{
public:
    void f() override;
};

// error: no "void D::f()" member function declared in class "D"
void D::f() {
    std::cout << "D::F";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...