我一直在阅读dynamic_cast
如何工作,从我到目前为止收集的内容,它获取对象,获取vptr,转到vtable,在-1或0元素中,有一个指向一个type_info
个对象。但是,从这一点来看,它有点模糊:
type_info
对象是否包含(可能)执行转换所需的所有数据,或者运行时系统是否需要访问其他type_info对象?
我试图了解在dynamic_cast
期间检查继承层次结构时访问了多少个不同的对象/ vtable和type_info对象。
编辑:编译方式MSVC或GCC
答案 0 :(得分:0)
这是未指定的,取决于实施,但是
有关将指针转换为另一种类型的信息
层次结构,至少在涉及虚拟继承时,
取决于实际最派生的类;找到了
class是D
,来自B
或C
的信息不帮助
在A
中查找D
的实际地址。的立场
对象中的A
部分将根据最大程度而不同
派生类。要清楚地看到这一点,请使用数据创建类
成员,并显示不同的地址:
struct B
{
int b;
B() : b( 1 ) {}
virtual ~B() = default;
};
struct L : virtual public B
{
int l;
L() : l( 2 ) {}
};
struct R : virtual public B
{
int r;
R() : r( 3 ) {}
};
struct D: public L, public R
{
int d;
D() : d( 4 ) {}
};
struct E : public D
{
int e;
E() : e( 5 ) {}
};
template <typename T>
class HexDump
{
T const& myObj;
public:
HexDump( T const& obj ) : myObj( obj ) {}
friend std::ostream& operator<<( std::ostream& dest, HexDump const& obj )
{
dest.fill( '0' );
dest.setf( std::ios_base::hex, std::ios_base::basefield );
uint32_t const* p = reinterpret_cast<uint32_t const*>( &obj.myObj );
for ( int i = 0; i < sizeof(T) / sizeof(uint32_t); ++ i ) {
if ( i != 0 ) {
dest << ' ';
}
dest << std::setw( sizeof(uint32_t) * 2 ) << p[i];
}
return dest;
}
};
template <typename T>
HexDump<T>
hexDump( T const& obj )
{
return HexDump<T>( obj );
}
int
addrDiff( void const* lhs, void const* rhs )
{
return static_cast<char const*>( lhs ) - static_cast<char const*>( rhs );
}
int
main()
{
B* aD = new D;
B* anE = new E;
std::cout << "position of B in D: " << addrDiff( aD, dynamic_cast<D*>( aD ) ) << std::endl;
std::cout << "position of B in E: " << addrDiff( anE, dynamic_cast<E*>( anE ) ) << std::endl;
std::cout << "D: " << hexDump( *dynamic_cast<D*>( aD ) ) << std::endl;
std::cout << "E: " << hexDump( *dynamic_cast<E*>( anE ) ) << std::endl;
return 0;
}
各种数据元素的初始化允许您查看 不同类别(或其有效载荷)的位置 清楚。
特别注意B
子对象的vptr在D
和B
中是不同的。它指向的vtbl中的RTTI信息必须反映最派生的类。