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

Вот пример множественного наследования. Я использовал оператор разрешения области видимости для разрешения неоднозначности вместо виртуального класса.

struct A 
{
    int i;
};

struct B : A
{};

struct C : A
{};

struct D: B, C 
{
    void f()
    {
        B::i = 10;
    }
    void g()
    {
        std::cout << B::i <<std::endl;
    }
};

int main() 
{
    D d1;
    d1.f();
    d1.g();
    return 0;
}

Является B::i хорошо сформированные?

2 ответа

Решение

Является B::i хорошо сформированные?

Да, это. Наиболее подходящая ссылка - [class.qual] / 1:

Если спецификатор вложенного имени квалифицированного идентификатора назначает класс, имя, указанное после спецификатора вложенного имени, ищется в области действия класса, за исключением случаев, перечисленных ниже. Имя должно представлять одного или нескольких членов этого класса или одного из его базовых классов.

Который указывает, что вы можете назвать i из-за того, что он является членом Bбаза. Доступность проверяется только после этого, и в вашем случае она общедоступна.

[class.access.base] / 5

... Доступ к члену зависит от класса, в котором он назван. Этот класс именования является классом, в котором имя члена было найдено и найдено... Член m доступен в точке R, если он назван в классе N, если

  • существует базовый класс B из N, который доступен в R, и m доступен в R, когда назван в классе B.

Да. Это выдержка из стандартных правил грамматики C++:

id-expression:
  unqualified-id
  qualified-id

postfix-expression:
  [...]
  postfix-expression . template[opt] id-expression
  [...]

В [class.mcft.non-static]:

Когда id-выражение (8.1), которое не является частью синтаксиса доступа к члену класса (8.2.5) и не используется для формирования указателя на член (8.3.1), используется в члене класса X в контексте, где это может быть использован (8.1.2), если поиск по имени (6.4) разрешает имя в выражении id в нестатический нетипичный член некоторого класса C, и если либо id-выражение потенциально оценивается, либо C является X или базовый класс X, id-выражение преобразуется в выражение доступа к члену класса (8.2.5) с использованием (*this) (12.2.2.1) в качестве выражения postfix слева от. оператор.

Другие вопросы по тегам