C++中高效的运行时类型检查
Efficient run-time type checking in C++
我有两个名为"表达式"和"BinExp"的类作为以下代码:
class Expression
{
public:
virtual BinExp* IsBinaryExp() { return NULL; }
};
class BinExp : public Expression
{
public:
virtual BinExp* IsBinaryExp() { return this; }
};
例如,我的指针变量类型为 Expression*
但初始化为 new BinExp
并作为参数发送到 analyse
函数,如以下代码所示:
int main()
{
Expression* e = new BinExp;
analyse(e);
}
在 analyse
函数中,我需要知道e
是指向Expression
类型还是BinExp
类型的指针。在我手里,有三种方法可以做到这一点。
第一:
BinExp* be = e->IsBinaryExp();
if ( be )
{
printf("Yes, `e` is a binary expressionn");
}
第二:
BinExp* be = dynamic_cast<BinExp*>(e);
if ( be )
{
printf("Yes, `e` is a binary expressionn");
}
第三个:
if ( typeid(*e) == typeid(BinExp) )
{
BinExp* be = e->IsBinaryExp(); // or dynamic_cast<BinExp*>(e);
printf("Yes, `e` is a binary expressionn");
}
但是我想知道当我需要在性能很重要的循环中频繁执行检查时,哪种方法(或任何其他方法)会更有效。任何建议,我将不胜感激。
最快的方法是保留一个成员变量,比如一个枚举,然后在基类中定义一个内联 getter,然后你可以比较结果是否是你期望的。
示例(未编译,可能会发生一些错误):
enum eExpTypes {
ET_UNDEFINED,
ET_BINARY
}
class Expresion
{
protected:
eExpTypes myType;
public:
Expresion(): myType(ET_UNDEFINED){};
inline eExpTypes getType(){return myType;};
}
class BinExpresion : public Expresion
{
public:
BinExpresion():myType(ET_BINARY){};
}
性能提升 :
- 您将取出两个数字:从指针到 VFPtable,从 VFPTABLE 到 函数
- 如果类型函数是唯一的虚拟函数,您的班级规模会更小
动态转换通常比制作自己的类型检查机制慢,因此在您的 3 个示例中,第一个应该是最快的。
最快的是:
e->printIsBinExp();
你在哪里制作那个虚拟方法,要么打印,要么是一个noop。
我只是在开玩笑。virtual
方法的要点是封装不同类型的对特定方法的处理 - 而不是编写一个程序来简单地对不同的运行时类型进行运行时切换。
假设dynamic_cast
最快。然后你会写:
if (BinExp* be = dynamic_cast<BinExp*>(e)) {
// ...
}
else if (UnExp* ue = dynamic_cast<UnExp*>(e)) {
// ...
}
else if (TernExp* te = dynamic_cast<TernExp*>(e)) {
// ...
}
希望不是。该代码将非常脆弱。您肯定想出这样的设计:
e->eval();
只是做正确的事情作为单一virtual
调用。
数字 3 是最优雅的。
为了找出是否或哪一个是最有效的,可以使用一些简单的代码来测量每个案例的执行时间......
#include <iostream>
#include <chrono>
/*
Case
*/
int main()
{
const clock_t begin_time = clock();
// Case
std::cout << float(clock() - begin_time) / CLOCKS_PER_SEC;
system("pause");
return 0;
}
相关文章:
- C++ 模板类型检查标准::is_same不起作用?
- C++将一个指针分配给另一个指针时执行的类型检查
- 为什么 std::bind 静态类型检查传递给函数的参数?
- 避免使用 std::any 编写相同的重复类型检查代码
- 标准::enable_if类型检查
- 有没有办法在 C++17 中创建编译时类型映射以进行类型检查?
- 如果方法不进行类型检查,为什么C++模板匹配?
- 输入数据类型检查循环未按预期工作 (C++)
- 在编译时使用可变参数模板在 c++ 中使用参数类型检查获取函数的参数数
- 标准::键映射和/或 boost::any 类型的值的类型检查
- 类型检查的编译时失败
- 带有类型检查的可变参数模板
- 通过SWIG禁用python-c 接口的隐式类型检查代码
- C++SFINAE运算符/函数结果类型检查
- C 功能返回模板类型检查
- Dynamic_cast类型检查功能没有铸件
- C++模板元编程静态类型检查
- 仅当我提供类型检查规则时才"No type checking rule"错误
- Do模板提供类型检查
- 类型检查:查看变量是继承的还是某个类