gpt4 book ai didi

c++ - 我应该怎么做才能看到实际的静态和动态绑定(bind)? [C++]

转载 作者:太空宇宙 更新时间:2023-11-04 13:43:55 26 4
gpt4 key购买 nike

我在 Linux 上使用 GCC。

我希望了解有效的虚拟函数。

我应该编写什么样的 C++ 代码来查看和理解使用和不使用虚拟函数时静态和动态绑定(bind)是如何发生的?

以及如何“看到”它们最终是如何绑定(bind)的,以及在这个过程中到底发生了什么?

最佳答案

这是一个例子。您可以构建和运行此代码,并将函数设置为虚函数或不虚函数。要获得虚拟行为、动态调度、动态绑定(bind),请使用预处理器宏构建它 IS_VIRTUAL定义。要查看静态绑定(bind),请在不定义该宏的情况下构建它。

#include <iostream>

#if defined(IS_VIRTUAL)
#define CONDITIONAL_VIRTUAL virtual
#else
#define CONDITIONAL_VIRTUAL
#endif

struct A {
CONDITIONAL_VIRTUAL void foo() { std::cout << "A\n"; }
};

struct B : A {
CONDITIONAL_VIRTUAL void foo() { std::cout << "B\n"; }
};

// global objects
A a; B b;

enum object_type { get_A, get_B };
A *get_object(object_type t) {
switch (t) {
case get_A: return &a;
case get_B: return &b;
}
}

int main() {
std::cout << "Choose A or B: ";
char c;
std::cin >> c;

A *x = get_object( c == 'A' ? get_A : get_B );
x->foo();
}

绑定(bind)与 x->foo() 的评估相关.编译器必须弄清楚要为该表达式执行什么代码。对于静态和动态绑定(bind),编译器查看 x并看到它的类型是 A* , 所以它会查看 struct A并寻找 foo()声明。

对于静态绑定(bind),编译器发现 foo()不是 virtual ,因此编译器会继续生成调用 foo() 的代码方法。简单。

使用动态绑定(bind),编译器会看到标记为 virtual 的方法,因此编译器生成的代码将在运行时使用与对象 x 关联的函数指针表。选择要调用的方法,然后调用找到的任何方法。编译器还在别处生成代码来为全局 a 创建表。和 b对象。对于全局 a对象它使表指向A::foo() , 以及全局 b它使表指向 B::foo() .所以如果x指向 b对象,那么表查找将导致 B::foo()这就是将要调用的函数。

一般来说,编译器必须确保所有具有虚方法的对象也有一个表,指向要调用的正确函数,以便任何时候对对象进行虚调用,程序可以,在运行时,获取与对象关联的表并查找要调用的正确方法。

因此,在静态和动态模式下构建上述程序,然后运行它并观察每个输入获得的输出。在下表中填写每种输入和绑定(bind)类型组合的输出。

       Binding |   static     dynamic
Input
-----
A ? ?
B ? ?

在所有情况下,输出都是由相同的 x->foo() 的评估产生的方法调用。在哪些情况下动态约束证据?这是否符合您对上述动态绑定(bind)解释的理解?

关于c++ - 我应该怎么做才能看到实际的静态和动态绑定(bind)? [C++],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26706605/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com