Могу ли я переопределить только один метод в наследовании?

мой C++ код выглядит следующим образом:

#include<iostream>
using namespace std;

class A
{
public:
virtual void f(int i)
{
cout << "A's f(int)!" << endl;
}
void f(int i, int j)
{
cout << "A's f(int, int)!" << endl;
}
};

class B : public A
{
public:
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};

int main()
{
B b;
b.f(1,2);
return 0;
}

во время компиляции я получаю:

g++ -std=c++11 file.cpp
file.cpp: In function ‘int main()’:
file.cpp:29:9: error: no matching function for call to ‘B::f(int, int)’
file.cpp:29:9: note: candidate is:
file.cpp:20:16: note: virtual void B::f(int)
file.cpp:20:16: note:   candidate expects 1 argument, 2 provided

Когда я попытался использовать переопределение после B (F), я получил ту же ошибку.

Возможно ли в C ++ переопределить только 1 метод? Я искал пример кода, используя override который скомпилируется на моей машине и еще не нашел.

5

Решение

Вы переопределяете имя «f» как имя метода. Таким образом, любая перегрузка также будет отменена.

Вы могли бы использовать using Ключевое слово, просто сказать компилятору, чтобы он смотрел и на базовый класс:

class B : public A
{
public:
using A::f;
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
5

Другие решения

Проблема в том, что ваша виртуальная функция f() в классе B шкуры Aне виртуальная перегрузка с одинаковым именем. Вы можете использовать using декларация, чтобы привести его в сферу:

class B : public A
{
public:
using A::f;
//  ^^^^^^^^^^^

virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
10

Вы укушены тем, как поиск имен работает в C ++. Компилятор просматривает последовательные области, пока не найдет область с хотя бы одним элементом с соответствующим именем.

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

Однако вы можете получить его для поиска класса родителя в этом случае:

class B : public A
{
public:
using A::f;
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};

На первый взгляд может показаться, что using Заявление может привести к двусмысленности. Например, с using A::f; есть сейчас два f(int) функции, видимые в BСфера (A::f(int) а также B::f(int)). C ++ имеет некоторые правила, чтобы покрыть это, так что если вы добавите (например) b.f(3); в mainusing A::f; на месте) вы все еще не получите двусмысленность — это позвонит b::f(int) как и следовало ожидать.

4

Функция f определенный в производном классе скрывает функции базового класса под именем f,
Чтобы вывести скрытую функцию в область видимости производного класса, вам нужно добавить:

using A::f;

к определению вашего базового класса.

Хорошо для чтения:

В чем смысл, Предупреждение: Derived :: f (char) скрывает Base :: f (double)?

1

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

0
По вопросам рекламы [email protected]