В C++ статические функции-члены наследуются? Если да, то почему не возникает ошибка неоднозначности?

Я только начинаю с gnu-cpp и хотел бы помочь. Я столкнулся с ошибкой неоднозначности во время чтения, и во время самостоятельного изучения я натолкнулся на мысль, что неоднозначная проблема с алмазом должна также затрагивать статические методы класса, но при выполнении следующего кода нет ошибки. Кто-нибудь может объяснить, почему?

#include<iostream>
using namespace std;
class Base
{
  public:
  static void display(){cout<<"Static";}
};
class Derived1 : public Base {};
class Derived2 : public Base {};
class Child : public Derived1, Derived2 {};
int main(void)
{
  Child obj;
  obj.display();
}

Спасибо за помощь и время.

3 ответа

Решение

Это хорошо в соответствии с правилами поиска. Вы видите, когда вы пишете членский доступ (obj.display();), член display ищется не только в рамках класса и его базовых классов. Подобъекты базового класса также принимаются во внимание.

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

Но когда они статичны, нет никакой двусмысленности. И чтобы было совершенно ясно, в стандарте C++ даже есть (ненормативный) пример, когда он описывает поиск членов класса (в разделе [class.member.lookup]):

[Примечание: Статический член, вложенный тип или перечислитель, определенные в базовом классе T, могут быть однозначно найдены, даже если объект имеет более одного подобъекта базового класса типа T. Два подобъекта базового класса совместно используют подобъекты нестатического члена их общие виртуальные базовые классы. - примечание конца] [Пример:

struct V {
  int v;
};
struct A {
  int a;
  static int   s;
  enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };

void f(D* pd) {
  pd->v++;          // OK: only one v (virtual)
  pd->s++;          // OK: only one s (static)
  int i = pd->e;    // OK: only one e (enumerator)
  pd->a++;          // error, ambiguous: two as in D
}

- конец примера]

Base::display что вы получаете через Derived1и Base::Display что вы получаете через Derived2, буквально одинаковые функции. Без учета контекста объекта (поскольку они статичны) здесь нет двусмысленности.

Да. Это унаследовано, потому что это член класса.

Там нет двусмысленности, потому что все, что называется obj.display() является то, что есть только один кандидат на выбор, конечный "источник" Base::display(),

Этот код, однако, генерирует ошибку:

class SuperBase {
    public:
    static void hello() { cout << "Super Base" << endl; }
};

class Base1 : public SuperBase {
    public:
    static void foo() { cout << "Base 1" << endl; }
};

class Base2 : public SuperBase {
    public:
    static void foo() { cout << "Base 2" << endl; }
};

class Derived : public Base1, public Base2 {
};

Derived obj;
obj.foo();  // Error: ambiguous resolution
obj.hello();  // No error here
Другие вопросы по тегам