C++ 虚拟方法未按预期调用
Posted
技术标签:
【中文标题】C++ 虚拟方法未按预期调用【英文标题】:C++ virtual method not called as expected 【发布时间】:2017-01-04 06:44:21 【问题描述】:我正在摆弄虚拟方法的正确覆盖。我链接了一些构造函数,并在基类构造函数中调用了一个虚拟方法。
调用链应该如下:
B(p)->A(p)->B.foo(p)
调用链在 C++ 中:
B(p)->A(p)->A.foo(p)
调用链在 C# 中:
B(p)->A(p)->B.foo(p)
也就是说,在 C# 中,行为符合预期,而在 C++ 中则不然。
C++ 代码:
#include <cstdio>
class A
public:
A();
A(int);
virtual void foo(int s);
;
class B : public A
public:
B();
B(int s) : A(s) ;
virtual void foo(int s) override;
;
A::A()
std::printf("A\r\n");
;
A::A(int s) : A()
std::printf("A: %d\r\n", s);
foo(s);
;
void A::foo(int s)
std::printf("A::foo(%d)\r\n", s);
B::B() : A()
std::printf("B\r\n");
;
void B::foo(int s)
std::printf("B::foo(%d)\r\n", s);
int main(int argc, char* argv[])
B b(2);
输出:
A
A: 2
A::foo(2)
C#代码:
using System;
namespace demo
class A
public A()
Console.WriteLine("A");
public A(int s) : this()
Console.WriteLine("A: " + s.ToString());
foo(s);
public virtual void foo(int s)
Console.WriteLine(string.Format("A:foo(0)", s));
class B : A
public B() : base()
Console.WriteLine("B");
public B(int s) : base(s)
public override void foo(int s)
Console.WriteLine(string.Format("B:foo(0)", s));
static class Run
static void Main()
new B(2);
输出:
A
A: 2
B::foo(2)
为什么在 C++ 中不调用类 B 的重写方法?如何正确覆盖它?
【问题讨论】:
在构造函数完成之前,虚拟调度不起作用。 ***.com/questions/962132/… 您说过 C++ 和 C# 的输出是相同的。你的意思是在 C# 中它调用 B::foo(2)? 不,输出不一样,C# 的行为符合预期,C++ 不是。我将输出添加到问题中。 【参考方案1】:这正是 C++ 的工作方式。虚函数在对象构造和销毁过程中不具有虚拟行为。
【讨论】:
为什么不呢?他们这样做 :) ,只是他们使用了作者没有预料到的 vtables以上是关于C++ 虚拟方法未按预期调用的主要内容,如果未能解决你的问题,请参考以下文章
调用 setGridLinesVisible(true) 时,GridPane 布局调试行未按预期显示