gpt4 book ai didi

C++ 类型比较 : typeid vs double dispatch dynamic_cast

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:04 24 4
gpt4 key购买 nike

是否有任何性能或稳健性原因使您更喜欢其中一个?

#include <iostream>
#include <typeinfo>

struct B
{
virtual bool IsType(B const * b) const { return IsType2nd(b) && b->IsType2nd(this); }
virtual bool IsType2nd(B const * b) const { return dynamic_cast<decltype(this)>(b) != nullptr; }
};

struct D0 : B
{
virtual bool IsType(B const * b) const { return IsType2nd(b) && b->IsType2nd(this); }
virtual bool IsType2nd(B const * b) const { return dynamic_cast<decltype(this)>(b) != nullptr; }
};

struct D1 : B
{
virtual bool IsType(B const * b) const { return IsType2nd(b) && b->IsType2nd(this); }
virtual bool IsType2nd(B const * b) const { return dynamic_cast<decltype(this)>(b) != nullptr; }
};

int main()
{
using namespace std;
B b, bb;
D0 d0, dd0;
D1 d1, dd1;

cout << "type B == type B : " << (b.IsType(&bb) ? "true " : "false") << endl;
cout << "type B == type D0 : " << (b.IsType(&dd0) ? "true " : "false") << endl;
cout << "type B == type D1 : " << (b.IsType(&dd1) ? "true " : "false") << endl;
cout << "type D0 == type B : " << (d0.IsType(&bb) ? "true " : "false") << endl;
cout << "type D0 == type D0 : " << (d0.IsType(&dd0) ? "true " : "false") << endl;
cout << "type D0 == type D1 : " << (d0.IsType(&dd1) ? "true " : "false") << endl;
cout << "type D1 == type B : " << (d1.IsType(&bb) ? "true " : "false") << endl;
cout << "type D1 == type D0 : " << (d1.IsType(&dd0) ? "true " : "false") << endl;
cout << "type D1 == type D1 : " << (d1.IsType(&dd1) ? "true " : "false") << endl;
cout << endl;
cout << "type B == type B : " << (typeid(b) == typeid(bb) ? "true " : "false") << endl;
cout << "type B == type D0 : " << (typeid(b) == typeid(dd0) ? "true " : "false") << endl;
cout << "type B == type D1 : " << (typeid(b) == typeid(dd1) ? "true " : "false") << endl;
cout << "type D0 == type B : " << (typeid(d0) == typeid(&bb) ? "true " : "false") << endl;
cout << "type D0 == type D0 : " << (typeid(d0) == typeid(dd0) ? "true " : "false") << endl;
cout << "type D0 == type D1 : " << (typeid(d0) == typeid(dd1) ? "true " : "false") << endl;
cout << "type D1 == type B : " << (typeid(d1) == typeid(bb) ? "true " : "false") << endl;
cout << "type D1 == type D0 : " << (typeid(d1) == typeid(dd0) ? "true " : "false") << endl;
cout << "type D1 == type D1 : " << (typeid(d1) == typeid(dd1) ? "true " : "false") << endl;
}

输出:

type B  == type B  : true 
type B == type D0 : false
type B == type D1 : false
type D0 == type B : false
type D0 == type D0 : true
type D0 == type D1 : false
type D1 == type B : false
type D1 == type D0 : false
type D1 == type D1 : true

type B == type B : true
type B == type D0 : false
type B == type D1 : false
type D0 == type B : false
type D0 == type D0 : true
type D0 == type D1 : false
type D1 == type B : false
type D1 == type D0 : false
type D1 == type D1 : true

最佳答案

从设计的角度来看,双重调度要灵活得多:

  • 目前您使用 IsType2nd(b) && b->IsType2nd(this) 检查类型之间的严格相等性。但可能在某个时候你想进一步推导

  • 但有一天您可能想要进一步派生 D1,但在比较类型时仍想将其视为 D1 对象所在的位置。这种特殊情况很容易用双重调度来完成。

这种灵 active 是有代价的:汇编代码将使用 2 个通过 vtable 的间接调用,以及一个动态转换。

直接的类型信息并不是最好的设计,正如 Sergey 所指出的:它将始终是严格的类型比较,不可能有特殊情况。

这种不灵 active 伴随着代码生成的简单性优势:代码只需在 vtable 的开头获取动态类型信息(并且编译器可以轻松地优化这种在编译时已知类型的对象的获取.

出于好奇,这里some code generated : typeid 在编译时被优化掉了,而 double displatch 仍然依赖于间接调用。

关于C++ 类型比较 : typeid vs double dispatch dynamic_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35371137/

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