Почему статический метод переопределяет нестатический метод базового класса?
struct B {
void foo () {}
};
struct D : B {
using B::foo;
static void foo () {}
};
int main ()
{
D obj;
obj.foo(); // calls D::foo() !?
}
Метод Member и метод члена static
полностью различаются по двум причинам:
-
static
не отменяет
виртуальные функции в базе class
- подпись указателя функции для обоих
случаи разные
Когда метод вызывается объектом, не должен ли метод-член иметь более высокое предпочтение логически? (Только то, что С++ позволяет вызывать метод static
с помощью объекта, будет ли он рассматриваться как переопределенный метод?)
Ответы
Ответ 1
Правило, которое вы видите, описано в ISO/IEC 14882: 2003 7.3.3 [namespace.udecl]/12:
Когда декларация использования приносит имена из базового класса в область производного класса, функции-члены в производном классе переопределяют и/или скрывают функции-члены с тем же именем и типами параметров в базовом классе (а не в конфликте).
Без этого правила вызов функции будет неоднозначным.
Ответ 2
Проблема здесь в том, что вы не можете перегружать статический метод, используя нестатический метод с той же сигнатурой.
Теперь, если вы попробуете:
struct D {
void foo () {}
static void foo () {}
};
Это приведет к ошибке.
Я не уверен, почему в случае using B::foo
он фактически игнорируется без предупреждения об ошибке/предупреждении (по крайней мере, в GCC 4.5.1).