我有以下代码示例:
class A
{
public:
A(int a):AA(a) {};
int AA;
virtual int Test()
{
return AA;
};
};
class B
{
public:
B(int b):BB(b) {};
int BB;
virtual int Test()
{
return BB;
};
};
class C:public A, public B
{
public:
C(int a, int b, int c) :A(a),B(b),CC(c) {};
int CC;
};
int main()
{
A *a = new C(1,2,3);
B *b = new C(1,2,3);
C *c = new C(1,2,3);
int x = a->Test() ; // this is 1
int y = b->Test() ; // this is 2
// int z = c->Test() ; // this does not compile
return 0;
}
我期待调用a-> Test()和b-> Test()也不明确,因为对象a是C,因此继承自A和B两者都具有相同的Test()功能。但是,它们都调用与delcared类型相对应的实现,而不是对象实际所在的类型。
有谁可以解释为什么这些电话不含糊不清? C ++总是这样做吗?
答案 0 :(得分:2)
实际上,C实例既是完整的A实例又是完整的B实例(因此拥有A方法和B方法的副本)
由于a是A *,编译器将使用C实例内部的A虚拟表副本 由于b是B *,编译器将使用C内部的B虚拟表副本 实例
你不能使用C *,因为编译器现在不想调用哪个A或B的Test()方法(因为C类同时包含A :: Test& B :: Test符号)
如果你实现了一个C :: Test()方法,那么它将被调用而不是A :: Test()& B :: Test()因为方法对A和A都是虚拟的。乙
答案 1 :(得分:0)
因为A
对C
的存在一无所知。
考虑稍微不同的情况:
<强> foo.h中强>
class A { public: virtual void Test() {} };
void myFunction(A *a);
<强> Foo.cpp中强>
#include "foo.h"
void myFunction(A *a) {
a->Test();
}
我猜你会想要这个编译吗?但是,如果我后来独立地继承自A,那会影响这段代码的编译吗?