我知道使用RTTI会造成资源损失,但它有多大?我看起来只是说"RTTI很贵",但它们实际上都没有给出任何基准或定量数据来控制内存,处理器时间或速度.
那么,RTTI有多贵?我可能会在我只有4MB RAM的嵌入式系统上使用它,所以每一位都很重要.
编辑:根据S. Lott的回答,如果我包括我实际做的事情会更好. 我正在使用一个类传递不同长度的数据,并且可以执行不同的操作,因此仅使用虚函数很难做到这一点.似乎使用少数dynamic_cast
s可以通过允许不同的派生类通过不同的级别但仍然允许它们以完全不同的方式行动来解决这个问题.
根据我的理解,dynamic_cast
使用RTTI,所以我想知道在有限的系统上使用它是多么可行.
这些代码中的哪一段更快?
if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}
Run Code Online (Sandbox Code Playgroud)
编辑:我知道他们不会做同样的事情.
我见过的几乎所有C++资源都讨论过这种事情告诉我,我应该更喜欢使用RTTI(运行时类型识别)的多态方法.总的来说,我认真对待这种建议,并会尝试理解其基本原理 - 毕竟,C++是一个强大的野兽,并且很难全面理解.然而,对于这个特殊的问题,我正在画一个空白,并希望看到互联网可以提供什么样的建议.首先,让我总结一下到目前为止我所学到的内容,列出引用为什么RTTI被"认为有害"的常见原因:
我真的不买这个论点.这就像是说我不应该使用C++ 14的功能,因为有些编译器不支持它.然而,没有人会阻止我使用C++ 14功能.大多数项目将对他们正在使用的编译器以及它的配置方式产生影响.甚至引用gcc手册页:
-fno-rtti
禁止使用虚拟函数生成有关每个类的信息,以供C++运行时类型标识功能(dynamic_cast和typeid)使用.如果您不使用该语言的那些部分,则可以使用此标志来节省一些空间.请注意,异常处理使用相同的信息,但G ++会根据需要生成它.dynamic_cast运算符仍可用于不需要运行时类型信息的强制类型转换,即强制转换为"void*"或转换为明确的基类.
这告诉我的是,如果我不使用RTTI,我可以禁用它.这就像说,如果你没有使用Boost,你就不必链接到它.我没有计划有人正在编译的情况-fno-rtti
.此外,在这种情况下,编译器将失败并且清晰.
每当我想要使用RTTI时,这意味着我需要访问我班级的某种类型信息或特征.如果我实现了一个不使用RTTI的解决方案,这通常意味着我将不得不在我的类中添加一些字段来存储这些信息,因此内存参数有点无效(我将进一步说明这一点).
事实上,dynamic_cast可能很慢.但是,通常有办法避免使用速度危急情况.而且我没有看到替代方案.这个SO答案建议使用在基类中定义的枚举来存储类型.这只有在您了解所有派生类时才有效.这是一个非常大的"如果"!
从这个答案来看,RTTI的成本似乎也不清楚.不同的人衡量不同的东西.
这是我认真对待的建议.在这种情况下,我根本无法提出覆盖我的RTTI用例的良好的非RTTI解决方案.让我举一个例子:
假设我正在编写一个库来处理某种对象的图形.我想允许用户在使用我的库时生成自己的类型(因此enum方法不可用).我的节点有一个基类:
class node_base
{
public:
node_base();
virtual ~node_base();
std::vector< std::shared_ptr<node_base> > get_adjacent_nodes();
};
Run Code Online (Sandbox Code Playgroud)
现在,我的节点可以是不同类型的.这些怎么样:
class red_node : virtual public node_base
{
public:
red_node();
virtual ~red_node();
void get_redness();
};
class yellow_node : virtual public node_base
{
public:
yellow_node();
virtual ~yellow_node();
void set_yellowness(int);
};
Run Code Online (Sandbox Code Playgroud)
见鬼,为什么不是其中之一:
class orange_node : public red_node, public yellow_node
{
public:
orange_node();
virtual ~orange_node();
void …
Run Code Online (Sandbox Code Playgroud) 纵观LLVM文件,他们提到,他们使用"RTTI的自定义窗体",这是他们的原因isa<>
,cast<>
和dyn_cast<>
模板功能.
通常,阅读一个库重新实现一种语言的一些基本功能是一种可怕的代码味道,只是邀请运行.但是,这是我们所说的LLVM:这些人正在研究C++编译器和 C++运行时.如果他们不知道他们在做什么,我会非常沮丧,因为我更喜欢Mac OS附带clang
的gcc
版本.
尽管如此,由于缺乏经验,我还是想知道正常RTTI的缺陷是什么.我知道它只适用于有v-table的类型,但只提出两个问题:
virtual
?虚拟析构函数似乎很擅长这一点.我正在使用gcc的-fno-rtti
标志来编译我的C++而没有运行时类型信息.
假设我没有使用dynamic_cast<>
或typeid()
,有什么东西可以引导我以后出现问题吗?
我有一个关于dynamic_cast
运算符的非常简单的问题.我知道这用于运行时类型识别,即在运行时了解对象类型.但是根据您的编程经验,您能否提供一个真实场景,您必须使用此运算符?没有使用它有什么困难?
我怎么运行这个main.cpp
:
#include <iostream>
#include <typeinfo>
using namespace std;
struct Blah {};
int main() {
cout << typeid(Blah).name() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过使用GCC 4.4.4版进行编译:
g++ main.cpp
Run Code Online (Sandbox Code Playgroud)
我明白了:
4Blah
Run Code Online (Sandbox Code Playgroud)
在Visual C++ 2008上,我会得到:
struct Blah
Run Code Online (Sandbox Code Playgroud)
有没有办法让它只是打印Blah
或struct Blah
?
我听说过很多关于Delphi 2010新的/改进的RTTI功能,但我必须承认我的无知......我不明白.我知道每个版本的Delphi都支持RTTI ......我知道RTTI(运行时类型信息)允许我在应用程序运行时访问类型信息.
但究竟是什么意思呢?Delphi 2010的RTTI支持与.NET中的反射相同吗?
有人可以解释为什么RTTI有用吗?假装我是你的尖头发老板,帮助我理解为什么RTTI很酷.我如何在实际应用程序中使用它?
我希望创建一个std::type_index
不需要RTTI的替代方案:
template <typename T>
int* type_id() {
static int x;
return &x;
}
Run Code Online (Sandbox Code Playgroud)
请注意,局部变量的地址x
用作类型ID,而不是其x
自身的值.另外,我不打算在现实中使用裸指针.我刚刚删除了与我的问题无关的所有内容.在这里查看我的实际type_index
实现.
这种方法听起来是否合理,如果是这样,为什么?如果没有,为什么不呢?我觉得我在这里不稳定,所以我对我的方法将会或不会起作用的确切原因感兴趣.
典型的用例可能是在运行时注册例程以通过单个接口处理不同类型的对象:
class processor {
public:
template <typename T, typename Handler>
void register_handler(Handler handler) {
handlers[type_id<T>()] = [handler](void const* v) {
handler(*static_cast<T const*>(v));
};
}
template <typename T>
void process(T const& t) {
auto it = handlers.find(type_id<T>());
if (it != handlers.end()) {
it->second(&t);
} else {
throw std::runtime_error("handler not registered");
}
}
private:
std::map<int*, …
Run Code Online (Sandbox Code Playgroud) rtti ×10
c++ ×8
gcc ×2
c# ×1
casting ×1
delphi ×1
delphi-2010 ×1
dynamic-cast ×1
g++ ×1
llvm ×1
performance ×1
polymorphism ×1
reflection ×1
templates ×1