【问题标题】:When is the constructor called by 'new' operator in C++C ++中的“new”运算符何时调用构造函数
【发布时间】:2013-10-20 08:02:48
【问题描述】:

自从我开始学习 C++ 以来,我一直读到“new”运算符在返回指向已分配内存的指针之前调用对象的构造函数。

所以,出于好奇,我检查了“新”的源代码,并在http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/new_op.cc?revision=197380&view=markup 找到了以下内容

_GLIBCXX_WEAK_DEFINITION void *
    operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
    {
      void *p;

      /* malloc (0) is unpredictable; avoid it.  */
      if (sz == 0)
        sz = 1;
      p = (void *) malloc (sz);
      while (p == 0)
        {
          new_handler handler = std::get_new_handler ();
          if (! handler)
            _GLIBCXX_THROW_OR_ABORT(bad_alloc());
          handler ();
          p = (void *) malloc (sz);
        }

      return p;
    }

我没有看到任何构造函数被调用或任何类型的机制来识别对象的类型。

那么,这是怎么做到的呢?编译器是否通过在分配的内存上调用构造函数来玩一些技巧?任何帮助将不胜感激。

此外,对于 new[](在下面的链接),不会进行任何条目来跟踪数组中的元素数量。那么,delete[] 怎么知道要销毁多少个元素呢?

http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/new_opv.cc?revision=195701&view=markup

我浏览了许多关于 SO 的相关问题,也搜索了它,但找不到答案。

【问题讨论】:

  • 非常感谢 Mike 和 Alexander。因此,在编译过程中,编译器必须添加额外的代码来调用构造函数和析构函数以防删除。我的理解正确吗?

标签: c++ constructor new-operator


【解决方案1】:

我没有看到任何构造函数被调用或任何类型的机制来识别对象的类型。

operator new 函数的工作只是分配内存;它不调用构造函数,甚至不知道将在内存中构造什么类型的对象(如果有)。它只是告诉分配多少字节。

编译器是否通过在分配的内存上调用构造函数来玩一些技巧?

如果“玩一些把戏”是指“生成一些代码”,那么是的。如果你使用new-表达式来创建一个对象,那么它会做两件事:

  • 调用operator new()为对象分配足够的内存;
  • 调用构造函数来初始化该内存中的对象。

此外,对于 new[](在下面的链接),不会进行任何条目来跟踪数组中的元素数量。那么,delete[] 怎么知道要销毁多少个元素呢?

new[] 表达式(不是operator new[])会在某处记录。具体细节留给实现。

【讨论】:

  • +1 用于清楚地区分 operator newnew-表达式(为 OP 提供了进一步挖掘的良好指针)。
【解决方案2】:

编译器是否通过在分配的内存上调用构造函数来玩一些技巧?

是的,上面看到的operator new只是获取内存块的部分的实现。在代码中使用new T 时,编译器会调用适当的operator new (size_t) 实现来获取内存块,然后在其上调用T 构造函数。

【讨论】:

    猜你喜欢
    • 2017-07-29
    • 2014-01-22
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多