gpt4 book ai didi

c++ - 在遗留代码上规避 RTTI

转载 作者:行者123 更新时间:2023-11-30 01:51:55 26 4
gpt4 key购买 nike

我一直在寻找一种方法来解决动态转换类型检查的缓慢问题。在你开始说我应该重新设计一切之前,让我告诉你,设计是 5 年前决定的。我无法修复之后的所有 400,000 行代码(我希望我可以),但我可以进行一些更改。我对类型识别进行了这个小测试:

#include <iostream>
#include <typeinfo>
#include <stdint.h>
#include <ctime>

using namespace std;

#define ADD_TYPE_ID \
static intptr_t type() { return reinterpret_cast<intptr_t>(&type); }\
virtual intptr_t getType() { return type(); }

struct Base
{
ADD_TYPE_ID;
};

template <typename T>
struct Derived : public Base
{
ADD_TYPE_ID;
};

int main()
{
Base* b = new Derived<int>();
cout << "Correct Type: " << (b->getType() == Derived<int>::type()) << endl; // true
cout << "Template Type: " << (b->getType() == Derived<float>::type()) << endl; // false
cout << "Base Type: " << (b->getType() == Base::type()) << endl; // false

clock_t begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
if (b->getType() == Derived<int>::type())
Derived <int>* d = static_cast<Derived<int>*> (b);
}
}
clock_t end = clock();
double elapsed = double(end - begin) / CLOCKS_PER_SEC;

cout << "Type elapsed: " << elapsed << endl;

begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
Derived<int>* d = dynamic_cast<Derived<int>*>(b);
if (d);
}
}
end = clock();
elapsed = double(end - begin) / CLOCKS_PER_SEC;

cout << "Type elapsed: " << elapsed << endl;

begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
Derived<int>* d = dynamic_cast<Derived<int>*>(b);
if ( typeid(d) == typeid(Derived<int>*) )
static_cast<Derived<int>*> (b);
}
}
end = clock();
elapsed = double(end - begin) / CLOCKS_PER_SEC;

cout << "Type elapsed: " << elapsed << endl;

return 0;
}

似乎使用类 ID(上面的第一次解决方案)将是在运行时进行类型检查的最快方法。这会导致线程问题吗?有没有更好的方法在运行时检查类型(不需要太多重构)?

编辑:我还可以补充一点,这需要与 TI 编译器一起使用,该编译器目前仅支持最多 '03

最佳答案

首先,请注意 dynamic_cast 和 RTTI 之间存在很大差异:强制转换告诉您是否可以将基础对象视为进一步派生的 some,但不一定最衍生的对象。 RTTI 会告诉您最精确的派生类型。自然前者更强大,也更昂贵。

那么,如果您有一个多态层次结构,您可以通过两种自然的方式来选择类型。他们是不同的;使用实际适用的那个。

void method1(Base * p)
{
if (Derived * q = dynamic_cast<Derived *>(p))
{
// use q
}
}

void method2(Base * p)
{
if (typeid(*p) == typeid(Derived))
{
auto * q = static_cast<Derived *>(p);

// use q
}
}

另请注意,如果基类是虚拟基类,则方法 2 通常不可用。如果您的类不是多态的,则这两种方法都不适用。

在快速测试中,我发现方法 2 比基于 ID 的手动解决方案快得多,后者又比动态转换解决方案(方法 1)快。

关于c++ - 在遗留代码上规避 RTTI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25495733/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com