мой 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
который скомпилируется на моей машине и еще не нашел.
Вы переопределяете имя «f» как имя метода. Таким образом, любая перегрузка также будет отменена.
Вы могли бы использовать using
Ключевое слово, просто сказать компилятору, чтобы он смотрел и на базовый класс:
class B : public A
{
public:
using A::f;
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
Проблема в том, что ваша виртуальная функция f()
в классе B
шкуры A
не виртуальная перегрузка с одинаковым именем. Вы можете использовать using
декларация, чтобы привести его в сферу:
class B : public A
{
public:
using A::f;
// ^^^^^^^^^^^
virtual void f(int i)
{
cout << "B's f(int)!" << endl;
}
};
Вы укушены тем, как поиск имен работает в 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);
в main
(с using A::f;
на месте) вы все еще не получите двусмысленность — это позвонит b::f(int)
как и следовало ожидать.
Функция f
определенный в производном классе скрывает функции базового класса под именем f
,
Чтобы вывести скрытую функцию в область видимости производного класса, вам нужно добавить:
using A::f;
к определению вашего базового класса.
Хорошо для чтения:
В чем смысл, Предупреждение: Derived :: f (char) скрывает Base :: f (double)?
Да, можно переопределить только один метод класса, сделать его виртуальным. Не виртуальный будет затенен при объявлении в унаследованном классе.