Отменить скрытие имени, используя ключевое слово "using". Не работает в классе внуков
Например, в приведенной ниже программе я отменяю скрытие имен, используя ключевое слово "using". Если у меня есть базовый и один производный класс, я получаю ожидаемую неоднозначную ошибку вызова. Но если у меня есть два производных класса (child и grand child), то теперь child и grand child имеют одну и ту же перегруженную функцию, и я отменяю скрытие имени, используя ключевое слово "using". Но это скомпилировано и получено. Мой вопрос, почему я не получаю ошибку как "неоднозначный вызов перегруженной функции".
class baseNameHiding
{
protected:
int nameHidingexample(int t)
{
cout<<"im baseeeeeeeeeeee"<<endl;
return 0;
}
};
class derivedNameHiding:public baseNameHiding
{
public:
float nameHidingexample(float s)
{
cout<<"im derived"<<endl;
return 0;
}
using baseNameHiding::nameHidingexample;
};
class grandDerivedNameHiding:public derivedNameHiding
{
public:
float nameHidingexample(float f)
{
cout<<"im grand derived"<<endl;
return 0;
}
using baseNameHiding::nameHidingexample;
using derivedNameHiding::nameHidingexample;
};
int main()
{
char a;float f = 0.0;
derivedNameHiding derived;
derived.nameHidingexample(0);
grandDerivedNameHiding grandchild;
grandchild.nameHidingexample(f);
cin>>a;
}
//output
im baseeeeeeeeeeee
im grand derived
1 ответ
Вы столкнулись со специальным правилом использования объявлений. C++14 [namespace.udecl]/15:
Когда объявление использования переносит имена из базового класса в область производного класса, функции-члены и шаблоны функций-членов в производном классе переопределяют и / или скрывают функции-члены и шаблоны функций-членов с одинаковыми именами, параметр-тип-список, cv -квалификация и ref-квалификатор (если есть) в базовом классе (а не конфликтующий). [...] [ Пример:
struct B { virtual void f(int); virtual void f(char); void g(int); void h(int); }; struct D : B { using B::f; void f(int); // OK: D::f(int) overrides B::f(int); using B::g; void g(char); // OK using B::h; void h(int); // OK: D::h(int) hides B::h(int) }; void k(D* p) { p->f(1); // calls D::f(int) p->f(’a’); // calls B::f(char) p->g(1); // calls B::g(int) p->g(’a’); // calls D::g(char) }
- конец примера ]