vs_rtti_类型识别的一些细节


#include <typeinfo>
#include <iostream>

class Person {
public:
	virtual ~Person() {}
};

class Employee : public Person { };

int main()
{
	Person person;
	Employee employee;
	Person* ptr = &employee;
	Person& ref = employee;

	std::cout << typeid(int).name() << std::endl;
	std::cout << typeid(Employee).name() << std::endl;
	{
		const auto* pType = &typeid(*ptr);
	}

	std::cout << typeid(ptr).name() << std::endl;
	std::cout << typeid(ref).name() << std::endl;
	//type_info
	return 0;
}

在这里插入图片描述

	{
		const auto* pType = &typeid(*ptr);
00C0DE09  mov         eax,dword ptr [ptr]  
00C0DE0C  push        eax  
00C0DE0D  call        ___RTtypeid (0BF54F9h)  
00C0DE12  add         esp,4  
00C0DE15  mov         dword ptr [ebp-48h],eax  
	}

``

跳进去看实现:
```cpp

extern "C" void * __CLRCALL_OR_CDECL __RTtypeid (
    void * inptr)            // Pointer to polymorphic object
    noexcept(false)
{
    if (!inptr) {
        throw std::bad_typeid::__construct_from_string_literal("Attempted a typeid of nullptr pointer!");   // WP 5.2.7
    }

    __try {
        const auto pCompleteLocator = GetCompleteObjectLocatorFromObject(inptr);
#if _RTTI_RELATIVE_TYPEINFO
        const auto _ImageBase = GetImageBaseFromCompleteObjectLocator(pCompleteLocator);
#endif

        if (((const void *)COL_PTD(*pCompleteLocator)))
        {
            return (void *) COL_PTD(*pCompleteLocator);
        }
        else {
            throw std::__non_rtti_object::__construct_from_string_literal("Bad read pointer - no RTTI data!");
        }
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
              ? EXCEPTION_EXECUTE_HANDLER: EXCEPTION_CONTINUE_SEARCH)
    {
        throw std::__non_rtti_object::__construct_from_string_literal("Access violation - no RTTI data!");
    }
}

在这里插入图片描述
这个很关键:
在这里插入图片描述


//
//	_RTTICompleteObjectLocator
//
typedef const struct	_s_RTTICompleteObjectLocator	{
	unsigned long							signature;
	unsigned long							offset;
	unsigned long							cdOffset;
#if _RTTI_RELATIVE_TYPEINFO
	int										pTypeDescriptor;	// Image relative offset of TypeDescriptor
	int										pClassDescriptor;	// Image relative offset of _RTTIClassHierarchyDescriptor
	int										pSelf;				// Image relative offset of this object
#else
	TypeDescriptor*							pTypeDescriptor;
	_RTTIClassHierarchyDescriptor*			pClassDescriptor;
 #if VERSP_WIN64	// TRANSITION, VSO#515783
	const _s_RTTICompleteObjectLocator* 	pSelf;
 #endif // VERSP_WIN64
#endif
	} _RTTICompleteObjectLocator;

在这里插入图片描述


#define COL_PTD(col)				((col).pTypeDescriptor)
``
显然返回的不是type_info 结构体
```cpp

#pragma warning(push)
#pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified
class type_info
{
public:

    type_info(const type_info&) = delete;
    type_info& operator=(const type_info&) = delete;

    size_t hash_code() const noexcept
    {
        return __std_type_info_hash(&_Data);
    }

    bool operator==(const type_info& _Other) const noexcept
    {
        return __std_type_info_compare(&_Data, &_Other._Data) == 0;
    }

    bool operator!=(const type_info& _Other) const noexcept
    {
        return __std_type_info_compare(&_Data, &_Other._Data) != 0;
    }

    bool before(const type_info& _Other) const noexcept
    {
        return __std_type_info_compare(&_Data, &_Other._Data) < 0;
    }

    const char* name() const noexcept
    {
        #ifdef _M_CEE_PURE
        return __std_type_info_name(&_Data, static_cast<__type_info_node*>(__type_info_root_node.ToPointer()));
        #else
        return __std_type_info_name(&_Data, &__type_info_root_node);
        #endif
    }

    const char* raw_name() const noexcept
    {
        return _Data._DecoratedName;
    }

    virtual ~type_info() noexcept;

private:

    mutable __std_type_info_data _Data;
};

typedef struct TypeDescriptor
{
#if defined(_WIN64) || defined(_RTTI) || defined(BUILDING_C1XX_FORCEINCLUDE)
	const void * pVFTable;	// Field overloaded by RTTI
#else
	unsigned long	hash;			// Hash value computed from type's decorated name
#endif
	void *	spare;			// reserved, possible for RTTI
	char			name[];			// The decorated name of the type; 0 terminated.
	} TypeDescriptor;

但是从二进制级别比较的话,其实TypeDescriptor 中的pVFTable 和
virtual ~type_info() noexcept; 重叠,由此,二进制级别是一样的.
在这里插入图片描述

算是vs 的常规操作吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值