所以我想知道为什么以下钻石问题的代码片段无法编译。我知道这个问题通常是通过虚拟继承来解决的,我不是故意使用这个的。这段代码只是为了展示我的问题,即编译器为什么会调用这种模棱两可的代码:因此,我在structBase中声明了两个成员变量,因为这两个子类(在本例中为structs(不是虚拟继承的,所以我将在每个派生结构中引用Base成员。现在我有了另一个结构AllDer,它将在知道id和name两次的问题上运行。然而,当我从Base显式地将id_和name_作为目标时,我不明白为什么这会是不明确的,因为直接目标变量是通过::-运算符指定的。
cout << Der1::Base::id_ << Der1::Base::name_ << 'n';
有人能告诉我,为什么编译器在这里遇到问题吗?(请原谅可能有错误的技术术语(编译器错误消息显示:"从派生类‘AllDer’到基类的转换不明确"。在QT Creator中使用MinGW 7.3.0 64位C++。
编辑:由于编译器对这个问题的处理方式不同,请检查相关问题。
#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?
}
};
Der1::Base
和Der2::Base
是同一个类,AllDer
从中派生两次。当您不是从Base
而是从Der1
:中选择成员时,您的方法会编译
struct AllDer : public Der1, public Der2
{
void readAllDer()
{
cout << Der1::id_ << Der1::name_ << 'n';
}
};
这是一个经典的菱形问题,即使您说您正在通过scope(:(指定直接目标变量这里"Der1"已经有"id_,name_"的副本,并且您仍在尝试访问base的副本,这对"AllDer"来说是不明确的,因为它通过Der1和Der2两种方式来实现。
而不是这个:
Der1::Base::id_
试试这个:
Der1::id_ and Der1::name_
希望这能帮助
您需要从类似的基类中继承Der1和Der2
struct Der1 : virtual public Base
struct Der2 : virtual public Base
在该链接中说:虚拟继承是一种C++技术,它确保孙子只继承基类成员变量的一个副本