我有两个名为' Expression'和' 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 expression\n");
}
第二
BinExp* be = dynamic_cast<BinExp*>(e);
if ( be )
{
printf("Yes, `e` is a binary expression\n");
}
第三个:
if ( typeid(*e) == typeid(BinExp) )
{
BinExp* be = e->IsBinaryExp(); // or dynamic_cast<BinExp*>(e);
printf("Yes, `e` is a binary expression\n");
}
但是我想知道当我需要在性能是一个问题的循环内频繁执行检查时,哪些方法(或任何其他方法)会更有效率。任何建议,我将不胜感激。
答案 0 :(得分:2)
最快的方法是保留一个成员变量,比如一个枚举,然后在基类中定义一个内联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){};
}
业绩增长:
动态强制转换通常比你自己的类型检查机制慢,所以如果你的3个例子,第一个应该是最快的。
答案 1 :(得分:0)
最快的将是:
e->printIsBinExp();
在哪里制作要打印或是noop的虚拟方法。
我只是部分开玩笑。 virtual
方法的要点是封装不同的类型&#39;处理特定方法 - 不要编写程序只是对不同的运行时类型进行运行时切换。
假设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
电话会议。
答案 2 :(得分:-1)
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;
}