假设我有基类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()。
由于
答案 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
方法就是被调用的方法。