Почему ссылка на базовый класс неоднозначна с :: -operator через производный класс? - PullRequest
3 голосов
/ 28 апреля 2020

Поэтому мне было интересно, почему следующий фрагмент кода проблемы алмаза не может быть скомпилирован. Я знаю, что эта проблема обычно решается с помощью виртуального наследования, я не использовал это нарочно. Код только для демонстрации моего вопроса о том, почему компилятор вызывает это неоднозначно: поэтому у меня есть две переменные-члены, объявленные в struct Base, потому что два подкласса (в данном случае структуры) не наследуются виртуально, у меня будет ссылка на Base члены в каждой производной структуре. Теперь у меня есть другая структура AllDer, которая запускалась бы при проблеме знания id_ и name_ два раза. Однако, когда я явно нацеливаюсь на id_ и name_ из Base, я не понимаю, почему это было бы неоднозначно, поскольку прямая целевая переменная указывается через оператор :: -.

cout << Der1::Base::id_ << Der1::Base::name_ << '\n';

Может кто-нибудь сказать мне, почему компилятор сталкивается с проблемой здесь? (Пожалуйста, прости, возможно, неправильные технические термины) Сообщение об ошибке компилятора гласит: «неоднозначное преобразование из производного класса« AllDer »в базовый класс». Использование MinGW 7.3.0 64-bit для C ++ в QT Creator.

РЕДАКТИРОВАТЬ: Поскольку кажется, что эта проблема по-разному обрабатывается компиляторами, пожалуйста, проверьте связанный вопрос.

#include <string>
#include <iostream>
using std::string; using std::cout;

struct Base
{
    int id_;
    string name_; //target members for readAllDer() in AllDer

    void read()
    {
        cout << id_ << ' ' << name_ << '\n';
    }
};


struct Der1 : public  Base
{
    //Der1 has own reference to id_, name_
    void readDer1()
    {
        cout << id_ << name_ << '\n';
    }
};

struct Der2 : public  Base
{
    //Der2 has own reference to id_, name_
    void readDer2()
    {
        cout << id_ << name_ << '\n';
    }
};

//
struct AllDer : public Der1, public Der2
{

    void readAllDer()
    {
        cout << Der1::Base::id_ << Der1::Base::name_ << '\n'; // Why is this ambiguous? 
    }
};

Ответы [ 3 ]

1 голос
/ 28 апреля 2020

Der1::Base и Der2::Base - это один и тот же класс, и AllDer наследуется от него дважды. Ваш метод компилируется, когда вы выбираете членов не из Base, а из Der1:

struct AllDer : public Der1, public Der2
{

    void readAllDer()
    {
        cout << Der1::id_ << Der1::name_ << '\n'; 
    }
};
0 голосов
/ 28 апреля 2020

Это классическая c проблема с алмазом, даже если вы говорите, что задаете прямую целевую переменную через scope (: :) Здесь в «Der1» уже есть копия «id_, name_», и вы все еще пытаетесь получить доступ Копия базы, которая является неоднозначной для «AllDer», так как она поступает двумя способами Der1 и Der2.

вместо этого:

Der1::Base::id_

попробуйте это:

Der1::id_ and Der1::name_

надеюсь, это поможет

0 голосов
/ 28 апреля 2020

вам нужно наследовать Der1 и Der2 виртуально от базового класса, как это

struct Der1 : virtual public  Base


struct Der2 : virtual public  Base

в этом LINK сказано: Виртуальное наследование - это метод C ++, который обеспечивает только одну копию базы переменные-члены класса наследуются внуком

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...