【问题标题】:Call class constructor from new operator on GNU - use invalid class从 GNU 上的 new 运算符调用类构造函数 - 使用无效类
【发布时间】:2011-03-18 15:46:51
【问题描述】:

与我的问题最接近的主题是here。我正在尝试使用 gcc 编译以下代码:

#include <malloc.h>

class A
{
public:
  A(){};  
  ~A(){};
};//class A

int main()
{
  A* obj = (A*) malloc( sizeof(A) );
  if(obj==0) return 1 ;
  obj->A::A(); /*error: invalid use of 'class A' */
  obj->A::~A();
  free(obj);
  return 0;  
};//

我从命令行编译代码:

$ g++ -o main main.cpp
main.cpp:在函数“int main()”中:
main.cpp:22:错误:“A 类”的使用无效

你能指出我正确的方向吗?

【问题讨论】:

  • 你为什么要这样做?当 new 失败时,您是否试图避免异常?只需使用 new (nothrow) 然后测试 NULL。
  • @Amardeep,我能想到的一个例子是网络服务服务器实现,在对象被序列化之前你不能删除它们,当它们被序列化时你没有控制线程,所以你不能调用析构函数,工具包或框架必须free那个。为您提供和管理的内存是通过malloc 进行的,那么除了使用它别无他法。 (如果他们不提供自定义的new 运算符,它会在他们的堆上分配并删除它们。)
  • @Amardeep :但我看到它看起来不像那种情况。所以 +1 你的问题。
  • @Gollum:我不相信。您对此网络服务器有任何引用吗?

标签: c++ gcc


【解决方案1】:

您想要一个新的展示位置。

void* ptr = malloc(sizeof(A));
A* obj = new(ptr) A;

【讨论】:

  • 在这种情况下分配器如何工作,就像它自己的堆一样?
  • @Gollum:如果您使用placement new,则不会进行任何分配。它只是将ptr 设置为this 并调用构造函数。
  • @KennyTM,正在谈论分配一个大缓冲区,然后为我需要在该大缓冲区上分配的所有对象(如 n 个字符串)执行多个 placement-new。 (如何放置 n 个对象,它应该有自己的算法来适应这些对象 - fragmentation
  • @Gollum:新展示位置与分配无关。它只是 places this 在它所接受的参数上,而不是调用构造函数。在我的回答中,是 malloc 行进行分配。
  • @Gollum:很好。您可能需要解决对齐问题,但从技术上讲,没有什么能阻止您将 10K(1 字节)对象或 5(2K)对象或您可以想到的任何组合放入 10K 块或分配的空间中。注意:块由您分配,因此您有责任管理碎片并最终酌情释放内存。至于向量,其大小在编译时是未知的 *这就是为什么向量如此有用,它在运行时调整大小)。
【解决方案2】:

您不能在对象上调用构造函数;构造函数只能在创建对象时调用,因此根据定义该对象尚不存在。

执行此操作的方法是放置new。没有必要投你的malloc 回报。它应该是void *,因为它不返回指向 A 的指针;只有一个指向您计划在其中构造 A 的原始内存的指针。

例如

void* mem = malloc( sizeof(A) );

A* obj = new (mem) A();
obj->~A();

free(mem);

【讨论】:

    【解决方案3】:

    C++ 中不需要malloc 业务。只需这样做:

    A* obj = new A();
    

    new 为你分配内存并调用构造函数。

    并且,要销毁它,请执行以下操作:

    delete a;
    

    delete 调用解构方法并释放内存。

    【讨论】:

      【解决方案4】:

      由于您使用的是 C++,因此无需回退到 malloc。可以写成运算符new

      int main() {
        if(A* obj = new (std::nothrow) A()) {
          delete obj;
          return 0;
        }
        return 1;
      }
      

      new 的 nothrow 版本在分配失败时返回空指针,而不是抛出异常。

      【讨论】:

        猜你喜欢
        • 2016-01-31
        • 2021-10-02
        • 2014-06-16
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        • 2015-12-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多