Почему статический метод переопределяет нестатический метод базового класса? - PullRequest
11 голосов
/ 16 июня 2011
struct B {
  void foo () {}
};

struct D : B {
  using B::foo;
  static void foo () {}
};

int main ()
{
  D obj;
  obj.foo();  // calls D::foo() !?
}

Метод члена и static метод члена совершенно различны по двум причинам:

  1. static метод не отменяет виртуальные функции в базе class
  2. Подпись указателя функции для обоих случаи разные

Когда метод вызывается объектом, разве метод логики члена не должен иметь более высокое предпочтение? (Только то, что C ++ позволяет вызывать метод static с использованием объекта, будет ли он рассматриваться как переопределенный метод ?)

Ответы [ 2 ]

9 голосов
/ 16 июня 2011

Правило, которое вы видите, описано в ISO / IEC 14882: 2003 7.3.3 [namespace.udecl] / 12:

Когда using-объявление переносит имена из базового класса в область производного класса, функции-члены в производном классе переопределяют и / или скрывают функции-члены с одинаковыми именами и типами параметров в базовом классе. (а не противоречащие друг другу)

Без этого правила вызов функции был бы неоднозначным.

1 голос
/ 16 июня 2011

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

Теперь, если вы попробуете:

struct D {
  void foo () {}
  static void foo () {}
};

Это вызовет ошибку.

Я не совсем уверен, почему в случае using B::foo он фактически игнорируется без вызова ошибки / предупреждения (по крайней мере, в GCC 4.5.1).

...