消除c ++中的diamond问题以访问顶级成员

时间:2018-08-23 20:02:03

标签: c++ language-lawyer multiple-inheritance

首先,我想承认many questions with similar titles和主题。我相当确定我的独特之处在于他们。

给出代码

struct Top {
    int get() {
        return 0;
    }
};

struct Mid1 : Top {
    int get() {
        return 1;
    }
};

struct Mid2 : Top {
    int get() {
        return 2;
    }
};

struct Bottom : Mid1, Mid2 {

};

int main(int argc, char ** argv) {
    Bottom b;
    std::cout << b.Mid1::get();
    std::cout << b.Mid2::get()
    std::cout << b.Top::get();
}

我尝试访问Top::get()时出现错误,并出现错误(使用gcc mingw-w64)

 error: 'Top' is an ambiguous base of 'Bottom'
 std::cout << b.Top::get();

我得到一个错误。在这种情况下,如何向编译器发出信号以在特定的继承路径上调用Top::get

2 个答案:

答案 0 :(得分:3)

Bottom是未使用derived classvirtual inheritance,因此它有两个Top的不同实例-一个实例是从Mid1继承的,另一个实例是从Mid2继承的Top。因此,您必须明确告知编译器要从哪个get()实例调用std::cout << b.Mid1::get(); // OK std::cout << b.Mid2::get(); // OK std::cout << b.Top::get(); // ERROR! std::cout << b.Mid1::Top::get(); // ERROR! std::cout << b.Mid2::Top::get(); // ERROR! std::cout << static_cast<Mid1&>(b).Top::get(); // OK std::cout << static_cast<Mid2&>(b).Top::get(); // OK ,例如:

Vector3

Live Demo

答案 1 :(得分:0)

您是否打算在Top中有两份Bottom的副本?如果是这样,请使用雷米·勒博的答案。但是,如果您想在Top中包含Bottom的单个副本,请使用虚拟继承:

struct Mid1 : virtual Top {...}
struct Mid2 : virtual Top {...}

在这种情况下,您的原始代码

std::cout << b.Top::get();

将编译。