У меня есть функция с тем же именем, но с другой сигнатурой в базовом и производном классах. Когда я пытаюсь использовать функцию базового класса в другом классе, который наследуется от производного, я получаю сообщение об ошибке. См. Следующий код:
class A
{
public:
void foo(string s){};
};
class B : public A
{
public:
int foo(int i){};
};
class C : public B
{
public:
void bar()
{
string s;
foo(s);
}
};
Я получаю следующую ошибку от компилятора gcc:
In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)
Если я удалю int foo(int i){};
из класса B
или переименую foo1
, все будет нормально.
Что с этим не так?
Ответы:
Функции в производных классах, которые не переопределяют функции в базовых классах, но имеют то же имя, будут скрывать другие функции с тем же именем в базовом классе.
Обычно считается плохой практикой иметь функции в производных классах, которые имеют то же имя, что и функции в классе bass, которые не предназначены для переопределения функций базового класса, поскольку то, что вы видите, обычно нежелательно. Обычно предпочтительнее давать разным функциям разные имена.
Если вам нужно вызвать базовую функцию, вам нужно будет ограничить вызов с помощью
A::foo(s)
. Обратите внимание, что это также отключит любой механизм виртуальных функцийA::foo(string)
одновременно.источник
Это потому, что поиск имени останавливается, если он находит имя в одной из ваших баз. В других базах дальше не пойдет. Функция в B затеняет функцию в A. Вы должны повторно объявить функцию A в области B, чтобы обе функции были видны из B и C:
class A { public: void foo(string s){}; }; class B : public A { public: int foo(int i){}; using A::foo; }; class C : public B { public: void bar() { string s; foo(s); } };
Изменить: настоящее описание, которое дает Стандарт (с 10.2 / 2):
В другом месте (чуть выше) он должен сказать следующее:
([...] поставлено мной). Обратите внимание, это означает, что даже если ваш foo в B является частным, foo в A все равно не будет найден (потому что управление доступом происходит позже).
источник
void A::foo(class basic_string<char,char_traits<char>,allocator<char> >)' in
классу B 'из-за локального метода `int B :: foo (int)' с тем же именем. Может быть, это потому, что я использую старую версию gcc