多早& &;实现了后期绑定
How Early & Late bindings are implemented?
当使用关键字virtual时,如果编译器-链接器知道调用者和被调用者的位置(地址/偏移量被保存在表中等),那么所有地址都可以在exe中硬编码。那么它不应该被称为早期绑定吗?如果只有在执行调用者代码时才获得地址(来自操作系统的地址?),那么这必须是真正的后期绑定。如果延迟绑定是首选,为什么编译器-链接器不想使用它(不管源代码是否使用了virtual关键字)?Saam
如果地址只在调用者代码执行时获得(来自操作系统的地址?)
它不是来自操作系统,而是(有效地)来自函数指针。
,那么这必须是真正的后期绑定。
。
如果延迟绑定是首选,为什么编译器-链接器不想使用它(不管源代码是否使用了virtual关键字)?
嗯,这不是首选。它要慢得多。这并不一定是因为"物理"函数调用比正常调用花费的时间要长得多;由于额外的间接性,它确实需要更长的时间,但真正的损害是,您的调用不能完全被忽略(通过内联),因为编译器不知道哪个函数将在运行时被调用。
你不希望使用它,除非你需要它,即你需要一个虚拟呼叫。
这个决定和你说"我应该直接调用一个函数,还是我应该从一堆选择中查找一个函数指针,然后像这样调用我想要的那个?"您使用了适合工作的工具,但是额外的灵活性是有代价的。
考虑这个例子:
#include <iostream>
#include <memory>
class Base {
public:
virtual void foo() = 0;
};
class Derived1: public Base {
public:
virtual void foo() { std::cout << "impl1" << std::endl; }
};
class Derived2: public Base {
public:
virtual void foo() { std::cout << "impl2" << std::endl; }
};
int main() {
int c;
std::cin >> c;
std::unique_ptr<Base> inst;
if (c) inst.reset(new Derived1());
else inst.reset(new Derived2());
inst->foo();
}
在这里,在真正运行程序之前,您不知道调用了哪个foo()实现。所以,是的,c++有真正的后期绑定。
延迟绑定的缺点是在调用虚拟方法时有一个很小的开销。由于c++可以在一些超级优化的计算库中使用,所以是否使用它的决定留给程序员。
正如Matteo Italia在评论中指出的那样,虚拟方法阻止了内联。这可能会对性能产生明显的影响(不像调用开销,它几乎永远不会被注意到)。
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在 C++14 中手动实现结构化绑定
- C ++实现全局开关/标志以控制程序行为的最佳方法,而无需将类绑定到公共点
- 实现功能对象绑定而无需使用C 11
- 如何在不必绑定到特定类的情况下实现观察者模式
- 隐马尔可夫模型-在C++中实现参数绑定
- 在C++中进行扩展后,将头绑定到实现
- C++实现的背包分支与绑定
- 对象实现后动态绑定大多数不相关的对象
- 错误:无法在实现文件中绑定“std::ostream”
- 我将如何在c++中实现动态绑定的这种使用
- 使用C++在android中理解和实现本机绑定器
- 结构化绑定实现地下层和std::元组
- c++ /Java绑定:应该在哪一边实现多线程
- 是否可以将cstdint类型定义绑定到某些特定于实现的类型std::numeric_limits没有专门针对的类型?
- 多早& &;实现了后期绑定
- 在C++中实现sql语句绑定的最佳方式