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

What will happen in this situation?

本文关键字:什么 这种情况下      更新时间:2023-10-16

假设我有一个基类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()

谢谢

函数重载是根据传入参数的静态类型来选择的。a静态类型A*,其动态类型B。图。

会发生两件事。首先确定调用哪个函数:

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声明为虚函数,虚函数表将以这样的方式构造,B的foo方法将在你的例子中被调用(因为对象是作为B类型创建的)。如果A::foo()没有被声明为虚函数,a的方法将被调用。

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

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

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

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