ambiguous access of

Прошу помочь мне разобраться в проблеме. В своем учебном проекте встретился с такой проблемой, но для вашего удобства перевел её в более простой вид. Ошибка восстановлена абсолютно идентично. КОД:

#pragma once
#include <iostream>
#include<vector>

class A
{
public:
    A() { var = 7; };
    ~A() {};

    int var;
};

class B 
{
public:
    B() {};
    ~B() {};
    
    std::vector <A> v;
    int var() { return v[0].var; }
};

class C : public A, public  B
{
public:
    C() {};
    ~C() {};
    int b;
};


int main()
{
    C * object = new C;
    std::cout << object->var << std::endl;
    delete object;
    system("PAUSE");
}

Код ошибки:

error C2385: ambiguous access of 'var'
note: could be the 'var' in base 'A'
note: or could be the 'var' in base 'B'

Я вижу причину в том, что в классе B у меня объявлен метод int var (), ибо если его имя изменить, то всё работает как нужно. Но мне не совсем понятно, почему эта ошибка возникает. Ведь я пишу std::cout<<object->var а не std::cout<<object->var().

При этом если поменять class C : public A, public B на class C : public В, public A то в дополнение к первой ошибке появится ещё и :

error C3867: 'B::var': non-standard syntax; use '&' to create a pointer to member

Что для меня тоже не совсем понятно. Очевидно, что я глупец и не понимаю какой-то простой вещи, поэтому прошу помощи. В моем понимании в данном примере наследование от класса А добавит в дочерний класс переменную int var, а наследование от B добавит переменную v, которая является вектором типа А, а так же метод var(). Короче говоря, понятно, что ничего не понятно. Объясните, пожалуйста, природу возникновения как первой ошибки, так и второй, очень хочется разобраться. Благодарю!


Ответы (1 шт):

Автор решения: Harry

При поиске имен откуда компилятору знать, что вы имеете в виду именно переменную A::var, а не адрес функции B::var()?

Используйте квалифицированное имя, и все будет в порядке:

std::cout << object->A::var << std::endl;

Так вы уберете неоднозначность.

Понятно, что

std::cout << object->B::var << std::endl;

не скомпилируется, но это уже будет ошибка компиляции после того, как четко выяснено, что же такое var.

→ Ссылка