在 C++ 中,运行时类型信息 (RTTI) 是否意味着动态绑定?
3 回答
RTTI 意味着附加信息包含在编译器输出中,以便运行时代码可以了解有关通常在编译中丢弃的源代码类和类型的详细信息。
例如,机器码不需要知道函数名就可以调用函数——在机器码中调用函数只需要知道目标函数的地址。
另一个例子:编译的机器代码在运行时不需要知道类类型的名称。但是,如果您想构建一个自动序列化库,您可能想知道每个类的文本名称,以便将其写入输出流。类名是 RTTI。
如果动态绑定是指能够在运行时通过字符串名称查找和调用在编译时未知的方法或属性,那么是的,RTTI 是一种可用于该目的的资源。
RTTI 表示在运行时确定引用(或指针)的动态类型:
class Base {};
class Dervied : public Base {};
Base* b ; // Static type of pointer is Base*;
b = new Base(); // Dynamic type (pointed to) is Base;
b = new Derived()' // Dynaic type pointed to is Derived.
RTTI 是在搞清楚 b 实际指向的是什么类型,也就是 b 的动态类型。
RTTI 很昂贵,而且形式不好。
使用公共继承,Derived is-a Base,所以函数不应该关心动态类型;无论 b 指向 Base 还是 Derived,它对 b 指向的任何东西都可以做的任何事情都应该没问题。
如果您的函数需要知道动态类型,则表明您在 Base 外部做一些事情,应该将其封装在base 中,作为您可以在 Base 上调用的方法。
如果你真的需要做一些外部的事情(你不能做,比如说,一个访客,因为外部的事情是多调度的),那么至少封装 RTTI 的(显着的)paet。让我们说重要的是它是否是Base:
class Base {
virtual bool isBase() { return true; }
};
class Dervied : public Base {
virtual bool isBase() { return false; }
}
如果突出的是类型,请执行以下操作:
class Base {
virtual string typeName { return "Base"; }
};
class Dervied : public Base {
virtual string typeName { return "Derived"; }
}
自然,既然我已经添加了一个虚函数,我需要添加一个虚 dtor,这意味着(三规则)我还应该添加一个复制 ctor 和复制赋值运算符。这些没有显示。
不,动态绑定是一个相当松散的术语,指的是在运行时根据某些上下文决定调用一组函数中的哪一个。它通常通过指向基类的指针来决定对象的实际类型,这通常称为虚成员函数。
RTTI 是一种在运行时发现对象的 type_info 对象的机制。虽然这两个概念有些相关,但它们彼此之间却截然不同。