【问题标题】:Casting pointer to object to void * in C++在 C++ 中将指向对象的指针转换为 void *
【发布时间】:2011-02-06 11:44:42
【问题描述】:

我一直在阅读 StackOverflow 并开始怀疑我曾经编写的所有代码,我一直在想“这是未定义的行为吗?”即使在已经运行了很长时间的代码中也是如此。

所以我的问题 - 将指向对象(在本例中为抽象接口类)的指针转换为 void* 然后将它们转换回原始类并使用它们调用方法是否安全且定义明确?

我完全清楚执行此操作的代码可能很糟糕。我现在什至不会考虑这样写(这是我真的不想更改的旧代码),所以我不是在寻找更好的方法来做这件事的讨论。如果我再次这样做,我已经知道如何写得更好。但是,如果在 C++ 中依赖它确实被破坏了,那么我将不得不考虑更改代码,如果它只是糟糕的代码,那么更改它就不会是优先事项。

一两年前我对这么简单的事情毫无疑问,但随着我对 C++ 理解的加深,我发现我越来越担心代码在标准下是否安全,即使它运行良好。有时读取过多的堆栈溢出可能对生产力不利:P

【问题讨论】:

    标签: c++ pointers casting


    【解决方案1】:

    你很安全。

    来自 C++(0x) 草案,

    §5.2.9/13(对于static_cast):

    对象指针类型的值转换为“指向cv void的指针”并返回,可能具有不同的cv限定,应具有其原始值。

    §5.2.10/7(对于reinterpret_cast):

    将“指向T1的指针”类型的右值转换为“指向T2的指针”类型(其中T1T2是对象类型并且T2的对齐要求不比T1) 并返回到其原始类型会产生原始指针值。

    (当然,转换为不相关的类是未定义的行为。)

    【讨论】:

    • 虽然这种行为在 C++0x 中当然没有改变,但我认为引用未接受的标准草案来回答有关语言当前状态的问题并不是一个好习惯。
    • 谢谢。经过 10 年的 C++ 编程,我觉得问这样一个基本问题相当愚蠢,但我对 C++ 了解得越多,有时我就越怀疑自己。其他人有这种感觉吗? ...嗯,那就只有我了。
    【解决方案2】:

    所以我的问题 - 将指向对象(在本例中为抽象接口类)的指针转换为 void* 然后将它们转换回原始类并使用它们调用方法是否安全且定义明确?

    是的——只要你转换回完全相同的类型。否则,基类指针调整可能会破坏指针的值。

    实际上,这(可能)仅在使用多重继承时才相关:指向派生类的指针的物理地址可能不同于指向其基类的指针。

    【讨论】:

      【解决方案3】:

      我们通常使用这种技术来避免根据您使用的环境(基于 Web、Windows、Linux 等)在每个类中使用 switch 语句

      使用void ** 作为参考。

      void ** detailObject;
      

      创建一个函数来返回被引用的对象:

      TheObject *TheClass::GetObject(){
          TheObject *object   =   (TheObject*)object;
          return object;
      }
      

      从现在开始只使用函数作为对象。例如GetObject()->Go();

      【讨论】:

        猜你喜欢
        • 2021-07-22
        • 1970-01-01
        • 1970-01-01
        • 2012-11-21
        • 1970-01-01
        • 2021-09-20
        • 2011-10-27
        • 1970-01-01
        相关资源
        最近更新 更多