代码之家  ›  专栏  ›  技术社区  ›  Mike Webb

C++删除语句的动态性是什么?

  •  4
  • Mike Webb  · 技术社区  · 14 年前

    这只是出于好奇,因为我没有用 new delete 在C++中除了最基本的用途之外。

    我知道。 删除 释放内存。我想知道的是,它是如何处理更复杂的案件的?

    例如,如果我有这样一个用户定义的类:

    class MyClass
    {
    public:
        MyClass();
        ~MyClass()
        {
            delete [] intArray;
        }
        //public members here
    private:
        int* intArray;
    };
    

    假设类以某种方式为 intArray ,然后在析构函数中释放它,如果我使用这样的类会怎么样: MyClass* myClass = new MyClass(); 后来发布了 delete myclass;

    怎么做? 删除 处理所有内存的释放?是否首先调用类析构函数以释放该类分配的所有内存(即 int* intArray )然后释放分配给该类的内存?

    如果我有这样一个班怎么办:

    class MyClass
    {
    public:
        MyClass();
        ~MyClass()
        {
            delete anotherMyClass;
        }
        //public members here
    private:
        MyClass* anotherMyClass;
    };
    

    假设 anotherMyClass 没有与构造函数一起分配,这会很快耗尽内存,如果有一个MyClasses链像链表一样相互连接会怎么样?在这种情况下,析构函数中的delete语句可以工作吗?会每个人 其他类别 在调用析构函数时递归释放?

    有什么特别的诡计或警告 新的 删除 你知道的陈述?

    2 回复  |  直到 9 年前
        1
  •  10
  •   James McNellis    14 年前

    给出一个指针( p )到动态分配的对象, delete 做两件事:

    1. 它调用动态分配对象的析构函数。注意,当 ~MyClass() 完成后,将调用类类型的任何成员变量的析构函数。
    2. 它释放动态分配对象所占用的内存。

    它不会在对象的成员变量中搜索其他指向空闲的指针;它不会释放任何其他内存,也不会执行任何其他操作。

    如果你需要释放 intArray ,你需要 删除 它在 MyClass .

    然而,在几乎所有的C++代码中,你不必担心这一点。你应该使用像这样的智能指针 shared_ptr , unique_ptr , auto_ptr scoped_ptr 自动管理动态分配的对象。人力资源管理充其量是困难的,应尽可能避免。

    这是一个更广泛的习惯用法的一部分,范围限制资源管理(SBRM,也称为资源获取是初始化,或RAII)。这是迄今为止理解和使用C++代码中最重要的设计模式。

    如果在你的班级里你已经声明了这一点:

    boost::scoped_ptr<int> intArray;
    

    然后当 scoped_ptr<int> 对象被破坏,它将释放它持有的指针。然后,您不必做任何工作来手动销毁对象。

    在编写良好的现代C++代码时,您很少需要手动使用。 删除 . 应该使用智能指针和其他SBRM容器来管理需要清理的任何类型的资源,包括动态分配的对象。


    在第二个示例中,给出一个如下所示的链接列表:

    x -> y -> z -> 0
    

    您的操作顺序如下:

    delete x;
      x.~MyClass();
        delete y;
          y.~MyClass();
            delete z;
              z.~MyClass();
                delete 0;
              [free memory occupied by z]
          [free memory occupied by y]
      [free memory occupied by x]
    

    链接列表中的对象将按相反的顺序销毁。

        2
  •  1
  •   Community noseratio    7 年前
    delete intArray;
    

    我想 intArray 指向的第一个元素 int 阵列?在这种情况下, delete intArray 产生未定义的行为。如果您通过 new[] 必须 通过发布 delete[]

    delete[] intArray;
    

    是的,我知道, 删除Intaray 可以 appear 在某些具有特定编译器版本的特定系统上,在某些编译器选项下,可以正常工作,否则可能不会。那是 undefined behavior 为了你。

    另外,你应该遵循 Rule of Three . 定义自己的析构函数,但依赖于隐式定义的复制构造函数和复制分配运算符,这是一个灾难的秘诀。