在这种情况下会发生什么?

时间:2011-07-06 20:26:07

标签: c++

假设我有基类A.它有方法

void foo(A* a);

它还有方法

void foo(B* b);

B继承自A。

假设我现在有一个B实例,但它是A * ex:

A* a = new B();

如果我打电话

 someA.foo(a);

这会调用方法的A *实现还是B *实现?

我正在为方法提供A *,但实际上该对象是B()。

由于

4 个答案:

答案 0 :(得分:6)

根据传递参数的静态类型选择函数重载。 a静态类型A*,只有动态类型B。去图。

答案 1 :(得分:3)

嗯,有两件事情会发生。首先确定要调用的函数:

A* a = new B();
foo(a);

这里你传递一个类型为A *的变量(C ++ =静态类型,记住)到foo,这将像往常一样调用foo(A* a),与任何其他函数重载没什么不同。如果您要致电foo(new B()),则会使用隐式类型B*并最终调用foo(B* b)。这里没什么新东西,普通的旧函数重载。请注意,仅当foo(B*)不存在时,由于继承,它将回退到更通用的版本。

现在在你的例子中我们来调用这个函数:

void foo(A* a)
{
    a->foo();
}

同样,标准C ++调用约定也适用,包括多态。这意味着如果你已经将foo声明为虚拟,那么vtable将以这样的方式构造,即为你的例子调用B的foo方法(因为对象被创建为类型B)。如果A::foo()未声明为虚拟,则将调用A本身的方法。

答案 2 :(得分:0)

我希望它使用foo(A *)方法,因为静态类型为A

但是,就像有人说的那样,添加一些日志记录并尝试检查哪一个正在执行。

答案 3 :(得分:0)

由于A::foo(A*)B::foo(B*)具有不同的签名(其参数类型),编译器会将它们视为完全不同的函数。如果不是同时调用两个方法foo(),而是调用了一个A::bar(A*)和另一个B::baz(B*),那么您将获得相同的行为。

foo(A*)A类型的所有对象的方法,B类型的所有对象也是A类型的对象,因为B是派生的来自A。所以foo()确实是对象someA的一种方法,它继承自父A类。这个方法A方法就是被调用的方法。