C++ C+的问题+';新';操作人员

C++ C+的问题+';新';操作人员,c++,language-features,new-operator,allocation,C++,Language Features,New Operator,Allocation,我最近遇到过 我不太理解文章中提到的几点: 作者提到了delete与delete[]之间的小麻烦,但似乎认为这实际上是必要的(对于编译器而言),但从未提供解决方案。我错过什么了吗 在函数f()中的“专用分配器”一节中,似乎可以通过将分配替换为:(省略对齐)来解决问题 “调试C++中的内存分配”。不能在这里争论 整篇文章似乎围绕着在自定义内存管理方案中具有重要构造函数和析构函数的类展开。虽然这可能是有用的,我也不能否认,但它的公共性相当有限 基本上,我们有新的和每类的分配器——这些方法不能解

我最近遇到过

我不太理解文章中提到的几点:

  • 作者提到了
    delete
    delete[]
    之间的小麻烦,但似乎认为这实际上是必要的(对于编译器而言),但从未提供解决方案。我错过什么了吗
  • 在函数
    f()
    中的“专用分配器”一节中,似乎可以通过将分配替换为:(省略对齐)来解决问题

  • “调试C++中的内存分配”。不能在这里争论

整篇文章似乎围绕着在自定义内存管理方案中具有重要构造函数和析构函数的类展开。虽然这可能是有用的,我也不能否认,但它的公共性相当有限

基本上,我们有新的和每类的分配器——这些方法不能解决什么问题

也,如果我只是粗略的头骨和疯狂,在<强>你的<强>理想C++中,什么会取代<代码>运算符new <代码>?根据需要发明语法——理想的语法是什么,只是为了帮助我更好地理解这些问题。

好吧,理想的语法可能是不需要任何形式的删除。有一个垃圾收集的环境,让程序员避免整个问题

咆哮中的抱怨似乎归结为

  • “我喜欢malloc做这件事的方式”
  • “我不喜欢被迫显式创建已知类型的对象”
  • 他说得对,您必须同时实现
    new
    new[]
    ,这一恼人的事实是正确的,但Stroustrups希望维护C语言的核心语义,这迫使您这样做。由于无法区分数组中的指针,因此必须自己告诉编译器。您可以解决这个问题,但这样做意味着从根本上改变语言C部分的语义;你不能再使用这个身份了

    *(a+i) == a[i]
    
    这将破坏所有C代码的很大一部分

    所以,你可以有一种语言

    • 实现了一个更复杂的数组概念,并消除了指针算法的奇迹,实现了带有摄影向量或类似内容的数组

    • 是垃圾收集的,因此您不需要自己的
      delete
      规程

    也就是说,你可以下载Java。然后,您可以通过更改语言来扩展它

    • 不是强类型,因此取消了类型检查
      void*
      upcast
    …但这意味着您可以编写代码,将Foo转换为Bar,而不让编译器看到它。如果您需要,这也将启用ducktyping

    问题是,一旦你完成了这些事情,你就有了一个C-ish语法的Python或Ruby

    自从Stroustrup发了CVAX 1的磁带以来,我一直在写C++。C++中涉及的许多历史现在都是出于对一个可以融入C世界的OO语言的渴望。大约在同一时间,还有很多其他更令人满意的语言问世,比如埃菲尔。C++似乎已经赢了。我怀疑它之所以获胜,是因为它可以融入C世界。

    好吧,理想的做法可能是不需要任何类型的删除。有一个垃圾收集的环境,让程序员避免整个问题

    咆哮中的抱怨似乎归结为

  • “我喜欢malloc做这件事的方式”
  • “我不喜欢被迫显式创建已知类型的对象”
  • 他说得对,您必须同时实现
    new
    new[]
    ,这一恼人的事实是正确的,但Stroustrups希望维护C语言的核心语义,这迫使您这样做。由于无法区分数组中的指针,因此必须自己告诉编译器。您可以解决这个问题,但这样做意味着从根本上改变语言C部分的语义;你不能再使用这个身份了

    *(a+i) == a[i]
    
    这将破坏所有C代码的很大一部分

    所以,你可以有一种语言

    • 实现了一个更复杂的数组概念,并消除了指针算法的奇迹,实现了带有摄影向量或类似内容的数组

    • 是垃圾收集的,因此您不需要自己的
      delete
      规程

    也就是说,你可以下载Java。然后,您可以通过更改语言来扩展它

    • 不是强类型,因此取消了类型检查
      void*
      upcast
    …但这意味着您可以编写代码,将Foo转换为Bar,而不让编译器看到它。如果您需要,这也将启用ducktyping

    问题是,一旦你完成了这些事情,你就有了一个C-ish语法的Python或Ruby


    自从Stroustrup发了CVAX 1的磁带以来,我一直在写C++。C++中涉及的许多历史现在都是出于对一个可以融入C世界的OO语言的渴望。大约在同一时间,还有很多其他更令人满意的语言问世,比如埃菲尔。C++似乎已经赢了。我怀疑它之所以获胜,是因为它可以融入C世界。

    这个叫嚣,IMHO,是非常误导人的,在我看来,作者确实理解更精细的细节,只是他似乎想误导。IMHO,显示参数中缺陷的关键点如下:

    void* operator new(std::size_t size, void* ptr) throw();
    
    本标准规定上述函数具有以下属性:

    返回:ptr

    注意事项:故意不执行其他操作

    重申-此函数故意不执行其他操作。这一点非常重要,因为它是placement new功能的关键:它用于调用对象的构造函数
    void* operator new(std::size_t size, void* ptr) throw();
    
    class A1 { };
    class A2 { };
    class B : public A1, public A2 { };
    
    void foo () {
        void * v = ::operator new (sizeof (B));
        B * b = new (v) B();  // Placement new calls the constructor for B.
        delete v;
    
        v = ::operator new (sizeof(int));
        int * i = reinterpret_cast <int*> (v);
        delete v'
    }
    
    template <typename T>
    class placement_pointer {
      // ...
      ~placement_pointer() {
        if (*count == 0) {
          m_b->~T();
        }
      }
      // ...
      T * m_b;
    };
    
    void
    f ()
    {
      arena a;
    
      // ...
      foo *fp = new (a) foo;           // must be destroyed
      // ...
      fp->~foo ();
    
      placement_pointer<foo> pfp = new (a) foo; // automatically !!destructed!!
      // ...
    }
    
    inline void *
    operator new[](size_t, void *place)
    {
      return place;
    }
    
    obj *
    f ()
    {
      void *p = special_malloc (sizeof (obj[10]));
      return new (p) obj[10];       // Serious trouble...
    }