【问题标题】:How to delete void pointer?如何删除空指针?
【发布时间】:2014-09-06 12:06:13
【问题描述】:

在 C++ 中删除这样的对象有什么问题吗?

MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;

【问题讨论】:

  • 将指针转换为void *,然后返回其原始类型可以保证保留其值。
  • §5.2.9/13 “对象指针类型的值转换为“指向 cv void 的指针”并返回,可能具有不同的 cv 限定,应具有其原始值。”
  • 你为什么要这样做?
  • @Jack Aidley,因为我想在C中使用一个C++类,所以必须使用void指针。
  • 我认为您可能应该发布一个更详细的问题,概述您在做什么以及为什么,因为我强烈怀疑如果您这样做的方式不太理想就是这样。

标签: c++ pointers void delete-operator


【解决方案1】:

这是合法的。

转换回MyCls* 至关重要。否则,您将调用未定义的行为——将不会调用 MyCls 析构函数,并且可能还会出现其他问题(例如崩溃)。您必须转换回正确的类型。

还要注意,如果涉及多重继承并使用多重转换,这可能会很复杂。您的演员表必须在任一方向“匹配”。

如果您的代码结构使得您在销毁时不知道类型,请为每个可删除对象提供一个带有虚拟析构函数的公共基类。然后在调用 delete 之前转换回基类。

【讨论】:

    【解决方案2】:

    代码定义明确。两种强制转换都是静态强制转换,尽管将其明确化(static_cast<void*>)而不是使用 C 风格强制转换是一种很好的风格。该标准规定,如果指向对象的指针通过静态强制转换转换为 void 指针并返回,它将保持其原始值。因此,您的最终delete 表达式应与delete c 具有相同的效果。

    话虽如此,void* 的使用通常是 C++ 中的代码异味。

    【讨论】:

    • 避免 C 风格转换的好建议。他们经常做的比你预期的要多。
    • @StilesCrisis 或者更糟糕的是,比您预期的要少
    • 避免void*的好建议。在希望 delete someVoidPointer; 工作的前 Java 程序员之后,我有很多战争故事...
    【解决方案3】:

    虽然这段代码是有效的,但这不是一个好的做法。

    作为一般准则,不应该有 news 和 deletes 在野外。尝试强制执行只有构造函数可以调用 new 并且只有析构函数可以调用 delete 的规则,这将帮助您更好地组织代码。

    如果您使用的是 C++11,请始终尝试std::shared_ptr 等,它会自动为您完成上述操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-21
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2013-09-09
      相关资源
      最近更新 更多