编译时和运行时的虚函数和非虚函数(c++)

Virtual and non-virtual functions during compile-time and runtime (C++)

本文关键字:函数 c++ 编译 运行时      更新时间:2023-10-16

希望标题没有让人混淆。我试图理解以下问题,从定义类的方法虚或不在c++中出现。假设我有一个基类a和一个派生类B,这样

class A { 
public:
    void print() { cout << "A"; } 
}
class B : A { 
public:
    void print() { cout << "B"; } 
}

如果我知道执行下面的代码,print命令将打印出"A"。

A *a = new A();
B *b = new B();
((A *)b)->print(); // this prints "A"

然而,如果我在两个类中声明"print"方法为虚方法,我将在屏幕上看到一个"B"。为什么会发生这种情况呢?

如果函数不是virtual,编译器将使用表达式给出的任何类型。因此,当您将B对象转换为A对象时,它将调用A::print函数。

如果你使用virtual,一个函数指针表[1]是由编译器构建的,当函数被调用时,编译器生成代码通过这个表调用,而不仅仅是查看当前类型,这允许基类型调用派生类中的函数,从而允许多态行为。

从技术上讲,规范没有告诉我们如何实现这一点,但这是几乎所有编译器的工作方式。如果编译器可以使用魔法产生相同的行为,那么允许这样做——只要魔法是可靠的和可复制的。

A *b = new b ();//LHS是编译时= RHS是运行时(coz' object是在运行时创建的)

B.print ();

如果print是非虚拟的:
编译时:a .print()被解析为去工作(因为它是一个真实的函数)
运行时:a .print()被部署/调度到工作。

如果print是虚函数/非实函数:
编译时:a .print()被绕过,B.print()被解析为继续工作B.print()被部署/分派到工作中。