【问题标题】:drawbacks of a void pointer in C++ [closed]C ++中空指针的缺点[关闭]
【发布时间】:2013-02-04 09:15:58
【问题描述】:

据我所知,C++ 中的 void 指针 void* 可以指向任何东西。如果我想在不使用某种继承的情况下开发解决方案,这可能非常有用(对我来说)。但是我想知道的问题是这种方法是否存在任何性能缺陷?

【问题讨论】:

  • 有什么性能缺陷?它只是一个指针,就像指向其他类型的指针一样。从您的实现描述看来,您正在尝试使用 C 方式解决 C++ 问题,但您不应该这样做。如果你想继承使用继承而不是void *
  • 主要的麻烦是弄清楚它实际上指向什么,以便正确地将其转换回去。如果你弄错了,如果你能马上发现错误,你就很幸运了。
  • 不会有性能缺陷,但您会丢失所有类型信息(从而丢失类型安全性)。这意味着编译器将无法发现错误,否则您将在运行时遇到它们(想想未定义的行为和难以跟踪的错误)。
  • 我不会担心性能缺陷。最大的缺点是你用void* 做的任何事情都会给你未定义的行为。我认为 void* 的唯一定义用途是将其转换回指向正确的类型。
  • 很容易出现性能缺陷。在某些时候,您必须在使用它之前弄清楚void* 的实际类型(除非您将它用作intptr_t)。如果该类型已经在程序中编码,则不需要该步骤。

标签: c++ pointers void


【解决方案1】:

void* 可以指向任何东西。如果我想在不使用某种继承的情况下开发解决方案,这可能非常有用(对我来说)

如果您正在考虑将void* 指针传递给某个函数,请考虑一下它的使用方式。为了调用此对象的方法或访问其成员,无论如何您都需要知道该对象的类型。

仅在您确实需要时使用void*。如果您正在寻找一种如何以更通用的方式处理对象的方法,那么只需进行适当的 OO 设计。当你有一个void* 指针时,你唯一知道的是“内存中这个地址有东西”,仅此而已。

使用void* 指针的性能与任何其他指针相同。您的代码的安全性可理解性以及与之相关的可扩展性可维护性应该是您的关注点。

【讨论】:

    【解决方案2】:

    是的 - 您可能会有一些性能缺陷。通过使用void *,您可以禁用基于严格别名假设的优化。

    例子

    void fun(void * param1, int & param2)
    {
        param2 = 7; // 1
        // do something with param1, param2 not used
        param2 += 1; // 2
    }
    

    如果没有 void * 变量,编译器可能会删除赋值 1 并在 2 中生成 param2 = 8。但现在不能,因为param1 可能指向param2,如果你调用fun(&i, i)

    More about strict aliasing

    【讨论】:

    • 你可能的意思是用 param2 做一些事情,param1 没有使用
    • 没有。我的意思是我写的。
    【解决方案3】:

    void* 有两个严重的性能缺陷。这 首先是它使理解和 维护程序,这对程序有严重影响 维护程序员的表现——以及 运行时,因为它使修改软件更加困难 当分析器显示您在哪里遇到性能问题时。 最快的程序是那些先写得好的程序, 因为这样就可以进行局部优化 关键的地方,而不必重写整个 程序。

    第二个性能影响是void* 可以别名 任何事物。正确的混叠分析是 编译器优化,以及你做的任何事情 困难会阻碍优化器,并可能导致代码变慢。 (char*unsigned char* 有类似的效果。)

    【讨论】:

    • +1 将明显的问题重新定义为性能问题。
    【解决方案4】:

    使用void* 时没有性能缺陷,除了编译器无法对其指向的类型做出假设之外。它仍然是一个指针。

    void* 在 C 中用于指向任意类型,因为任何指向对象类型的指针都可以转换为 void*。但是,用它做几乎任何事情都会导致未定义的行为。您只能安全地将其转换回原始指针类型。

    然而,在 C++ 中,我们有一种更好的方法来存储指向任意类型的指针——模板。对于一些模板参数T,我们可以有一个T*

    【讨论】:

    • Correct 可能正确但没用。我会使用 sameoriginal 这个词。
    • +5 表示模板
    【解决方案5】:

    可能仍然存在void* 大于其他类型的指针的平台,或者具有不同的格式,因此转换为void* 或从void* 转换为实际的转换代码。在普通(x86、ARM)硬件上,情况并非如此,所以void* 没有性能问题——你只是放弃了类型安全。

    【讨论】:

      【解决方案6】:

      最大的缺点是使用 void 指针会阻止编译器执行类型检查。尤其是在支持面向对象原则的语言中,我认为大量使用 void 指针会很奇怪。

      您更有可能在 C 中找到 void 指针来模仿一些多态行为,但同样存在类型安全问题。

      【讨论】:

      • +1 指出编译器的观点
      【解决方案7】:

      我不明白为什么在使用 void 指针而不是任何其他类型的指针时会出现任何性能问题。我会更关心安全性,你放弃了一个 void 指针。

      【讨论】:

        猜你喜欢
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 2014-01-07
        • 1970-01-01
        • 2018-05-27
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多