手头的问题很难描述,因此为了更清晰起见,代码被放在前面。
struct Base
{
int b;
virtual void foo(){cout << b << endl;}
Base(int x) : b(x){}
};
struct Derived1 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived1() : Base(1){}
};
struct Derived2 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived2() : Base(2){}
};
struct MultiInheritance : Derived1, Derived2
{
void bar1()
{
//needs to access Derived1's Base foo()
}
void bar2()
{
//needs to access Derived2's Base foo()
}
};
假设在一些奇怪的奇怪场景中,我希望基类MultiInheritance
有两个基类Derived1
和Derived2
,它们具有共同的非虚拟基类Base
。
Base
中有两个MultiInheritance
,如何指定我希望在Base
中访问哪个MultiInheritance
类?
上面的代码似乎可以通过多次转换来正常工作,但我不确定这是否是已定义的行为。如果是,编译器如何实现多态性的需求呢?一方面 virtual
调用应该都会产生相同的virtual
函数表,但另一方面,如果它发生则不会产生不同的答案。
修改
我想强调Base
类必须非虚拟
EDIT2
深深道歉,我严重歪曲自己。上面的代码更新更好地反映了我原来的问题。
答案 0 :(得分:2)
这被称为钻石问题。
http://www.cprogramming.com/tutorial/virtual_inheritance.html
如果你想保持base non-virtual并获得你现在正在寻找的行为,你可以通过以下方式在MultipleInheritance中执行此操作,以确保从正确的基类调用public class TestMemory {
public static void main(String [] args) {
int mb = 1024*1024;
//Getting the runtime reference from system
Runtime runtime = Runtime.getRuntime();
System.out.println("##### Heap utilization statistics [MB] #####");
//Print used memory
System.out.println("Used Memory:"
+ (runtime.totalMemory() - runtime.freeMemory()) / mb);
//Print free memory
System.out.println("Free Memory:"
+ runtime.freeMemory() / mb);
//Print total available memory
System.out.println("Total Memory:" + runtime.totalMemory() / mb);
//Print Maximum available memory
System.out.println("Max Memory:" + runtime.maxMemory() / mb);
}
}
函数
foo()
答案 1 :(得分:0)
MultiInheritance中有两个Base,如何指定哪个Base 我希望在MultiInheritance中访问哪个类?
您对
中要调用的基础对象存在歧义void MultiInheritance::bar1(){
foo();
}
解决这个问题的方法是告诉编译器在哪里寻找foo。
void MultiInheritance::bar1(){
Derived1::foo(); // The same foo() as in your question.
}
这是您的
所取得的成果void MultiInheritance::bar1()
{
Derived1& d = *this;
这在§10.2.12的标准中有所描述。这是明确的定义。
是你的链条void MultiInheritance::bar1()
{
Derived1& d = *this;
Base& b = *this;
同一段。
不幸的是,范围解析运算符无法让您从MultiInhteritance直接跳转到Base
MultiInheritance::foo(){
Derived1::Base::foo();
描述了嵌套类Base
。
要访问属于Base的foo(),您可以使用MultiInheritance中的范围分辨率语法,以及Derived1和Derived2中的范围分辨率语法。
Derived1()::foo(){
Base::foo;
如果这不合适,那么您建议的选项是剩余的选项。
如果是,编译器如何实现满足需求 多态性?一方面虚拟呼叫都应该导致 相同的虚函数表,但另一方面,如果它不这样做 输出不同的答案。
编译器实现因编译器而异,并且作为评论者声明:使用vtable进行虚函数是一个实现细节。如果实现使用vtable来实现虚拟功能,则实现需要考虑这种情况。
答案 2 :(得分:0)
这是一个更具说明性的例子。
#include <iostream>
using namespace std;
template <typename Res, typename Arg>
Res& as(Arg& arg)
{
return arg;
}
struct Base
{
virtual void foo() = 0;
};
struct Derived1 : Base {};
struct Derived2 : Base {};
struct MoreDerived1 : Derived1
{
void foo() { cout << "Derived1\n"; }
};
struct MoreDerived2 : Derived2
{
void foo() { cout << "Derived2\n"; }
};
struct MultiInheritance : MoreDerived1, MoreDerived2
{
void bar1() { as<Derived1>(*this).foo(); }
void bar2() { as<Derived2>(*this).foo(); }
};
int main ()
{
MultiInheritance m;
m.bar1();
m.bar2();
}
这个例子说明了:
Derived1::foo()
。 as
辅助函数只是一个语法糖,你也可以说
Derived1& d = *this;
d.foo();