【问题标题】:to get the real type information of a pointer in c++在 C++ 中获取指针的真实类型信息
【发布时间】:2021-01-29 01:28:21
【问题描述】:
class myclass1 {
public:
    virtual ~myclass1() {

    }
};

class myclass2 : public myclass1 {

};

int main() {

    myclass1 obj1;
    myclass2 obj2;

    myclass1 *p1 = &obj2;
    myclass2 *p2 = static_cast<myclass2 *>(&obj1);

    if( p1 && p2){
        cout << typeid(p1).name() << endl;
        cout << typeid(p2).name() << endl;
    }
}

输出如下:

P8myclass1
P8myclass2

Process finished with exit code 0

代码有两个类,我尝试使用两种类型的指针来指向另一种类型。从基类到它的子类是完全可以的,而反之则不行(“myclass2 *p2 = static_cast(&obj1);”)。如果我使用“dynamic_cast”,则转换后的指针将为空。但是如果我使用“static_cast”,当我使用 typeid 方法时,转换似乎成功并且类型是“myclass2”。

当我在 Clion 中处于调试模式时,调试器似乎知道指针的真实类型,如图所示。它知道 p1 的类型是“myclass2”,而 p2 的类型是“myclass1”。它有什么魔力?

obj1 = {myclass1} 
obj2 = {myclass2} 
p1 = {myclass2 * | 0x7ffeec114a08} 0x00007ffeec114a08
p2 = {myclass1 * | 0x7ffeec114a10} 0x00007ffeec114a10

【问题讨论】:

    标签: c++ pointers


    【解决方案1】:

    typeid(p1) 将为您提供指针p1 的类型,它始终为myclass1 *(字符串P8myclass1myclass1 * 类型的错位名称)。如果你想要指向对象的类型,你想要typeid(*p1),在这种情况下应该是myclass2

    对于 p2,typeid(p2) 将是 myclass2 *,而 typeid(*p2) 给出未定义的行为——在静态转换为错误类型后,您不能安全地取消引用指针。 很可能您会收到myclass1,但不确定——您可能会遇到崩溃。

    调试器本质上是通过额外的知识和保护来做到这一点,以避免未定义行为导致不良行为。

    【讨论】:

    • 谢谢。 typeid(*p2) 在这种情况下给我 p1 但是你的意思是这个结果并不总是这样吗?基本上我只想在做演员之前做一个安全的类型检查,或者至少我知道我做了错误的演员。似乎通过 dynamic_cast 我可以通过检查返回的指针是否为 NULL 来实现这一点。但是static_cast没有这种机制吗?所以我应该总是更喜欢动态案例而不是静态案例?
    • 正确——在不正确的 static_cast 之后取消引用指针会产生未定义的行为,因此你不能依赖你得到的——所以除非已知它是安全的,否则你不应该使用 static_cast。 dynamic_cast 的存在是为了进行这样的安全转换。
    【解决方案2】:

    “魔法”可能是未定义的行为。您不能static_cast 指向不同类型的指针,除非在特定情况下(如向上转型)。在您的情况下,&amp;obj1 指向 myclass1 对象,而不是 myclass2 对象,因此执行向下转换完全没有意义。

    【讨论】:

    • 您可以(安全地)进行静态转换——除了将结果指针静态转换回原始类型之外,您无法做任何事情。
    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多