【问题标题】:error: request for member is ambiguous c++;错误:对成员的请求不明确 C++;
【发布时间】:2021-01-25 07:19:37
【问题描述】:

我已经在 StackOverflow 上查看了几个类似的问题,但没有任何帮助。我不明白为什么我的班级 NetflixCanada 中的关键字 using 不能解决歧义。

我想要达到的目标: 第二次访问来自 NetflixUkraine 类的私有方法。

不管怎样,这是代码:

#include <iostream>
using namespace std;

void greetings(){
    cout << "\e[1mHi! This is a Netflix country review:\e[0m\n";
}

class NetflixUkraine {
    private:
    string mostPplrBrowserFrNTflx;

    public:
    string countryName; 
    int amountMedia = 5000;
    void uniqueMedia(){
        cout << "We have john Wick II\n";
    }
    
        void setBrowser(string amostPplrBrowserFrNTflx){
        if (amostPplrBrowserFrNTflx == "Chrome" || amostPplrBrowserFrNTflx == "Firefox" || 
        amostPplrBrowserFrNTflx == "Safari" || amostPplrBrowserFrNTflx == "Opera"){

            mostPplrBrowserFrNTflx = amostPplrBrowserFrNTflx;
        }

        else {
            mostPplrBrowserFrNTflx = "\nCannot define a web browser!\n";
        }
        }


        string getBrowser(){
            return mostPplrBrowserFrNTflx;
        }
};

class NetflixPoland: public NetflixUkraine { 
   public:
    void uniqueMedia(){
        cout << "We have john Wick II and III\n"; //method overriding
    }
   

   string doPolesLoveNtflx(bool answer){ //extending inheritance    
       if (answer == 1){
            return "Poles love Netflix";
       }
       else{
            return "Poles don't love Netflix";
       }
   }
};

class NetflixCanada: public NetflixUkraine, public NetflixPoland{
    public:
    using NetflixUkraine::setBrowser;
};

int main()
{
    greetings();

    //printing output
    NetflixUkraine library1;
    library1.countryName = "Ukraine";
    cout<< library1.countryName<<endl << library1.amountMedia << endl;
    library1.uniqueMedia(); //printing out the unique media


    NetflixPoland library3;
    library3.countryName = "\nPoland";
    cout << library3.countryName<< endl;
    library3.uniqueMedia();
    cout << library3.doPolesLoveNtflx(true) << endl;
    
    //adding a fav browser for watching Netflix
    library3.setBrowser("Chrome");
    cout << "most popular browser for watching Netflix: " << library3.getBrowser() << endl;

    NetflixCanada library4;
    library4.NetflixUkraine::setBrowser ("Chrome");

    return 0;
}

输出:


[12inheritance.cpp 2020-10-10 11:41:07.556]
,,12inheritance.cpp:65:7: warning: direct base ‘NetflixUkraine’ inaccessible in ‘NetflixCanada’ due to ambiguity
   65 | class NetflixCanada: public NetflixUkraine, public NetflixPoland{
      |       ^~~~~~~~~~~~~
12inheritance.cpp: In function ‘int main()’:
12inheritance.cpp:96:30: error: ‘NetflixUkraine’ is an ambiguous base of ‘NetflixCanada’
   96 |     library4.NetflixUkraine::setBrowser ("Chrome");
      |                              ^~~~~~~~~~

【问题讨论】:

  • 你的继承结构被称为“死亡之钻”。顾名思义,最好避免。您想了解虚拟继承。
  • NetflixUkraine 的继承层次结构中有两个基本实例NetflixCanada。在一些纸上画一个图表,它最好是显而易见的。最终,当您指定 library4.NetflixUkraine:: 和 @n.'pronouns'm. 时,编译器不知道您指的是哪一个,这里没有菱形,这是问题的一部分。相反,它是一个 Y 叉。钻石通过使用虚拟基类来形成形状,这里没有虚拟基类,在使用之前,OP 应该首先听取您的建议并质疑设计。
  • 另外,using namespace std; 与您的问题无关;它只是在调用 std 命名空间中的调用函数时节省了您键入 std:: 的时间。如果您正在学习 c++,我建议您避免使用 using namespace foo,直到您牢牢掌握了作用域的工作原理。
  • @user888379 我不是指使用命名空间标准;但使用 NetflixUkraine::setBrowser;
  • @max 我担心using namespace std; 是我的小毛病,我没有认真阅读您的问题。对此感到抱歉。

标签: c++ class methods ambiguity


【解决方案1】:

你的编译器无法区分:

NetflixCanada::NetflixUkraine::setBrowser

NetflixCanada::NetflixPoland::NetflixUkraine::setBrowser

如 cmets 中所述,请阅读 "The deadly diamond of death"

【讨论】:

  • 感谢您的解决方案 Pablo Yaggi。但是,现在我对应该检查哪个解决方案感到困惑:要么是“死亡的致命钻石”,要么来自 @WhozCraig “Y-fork”。
  • 概念差不多,文档中的信息描述性很强,所以才给你指出来。在我看来,你应该避免这种继承。
  • 我已经阅读了这篇文章,但不清楚为什么我不能执行以下操作:``` library4.amountMedia = 1200; ``` 根据您提到的文章,当我们处理方法或值覆盖时会出现“钻石问题”,但上面的代码确实没有这些。因此,为什么会发生,以及如何解决?谢谢。
  • 问题是一样的,不限于数值。问题是当编译器无法决定遵循哪条路径时。做下面的练习,解释编译器应该遵循什么,以及为什么。
猜你喜欢
  • 2020-10-14
  • 2014-07-10
  • 2010-11-21
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
相关资源
最近更新 更多