1

我有以下代码示例:

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++ 总是这样吗?

4

2 回答 2

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 和 B 都是虚拟的。

于 2012-06-28T09:35:39.080 回答
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 继承,那会影响这段代码是否编译吗?

于 2012-06-28T09:19:20.327 回答