<p>理解人们在这里提出的有效观点。不过,我的确有一个论点,即有时候“明星导入”可能并不总是一种不好的做法:</p> <ul> C + + 中的 delete 与 delete []运算符

  • 当我想把代码的结构设计成所有的常量都归入一个名为 const.py的模块时:

      在 C + + 中,deletedelete[]运算符的区别是什么?

  • 152123 次浏览

    delete操作符释放内存并调用用 new创建的单个对象的析构函数。

    delete []操作符释放内存并为用 new []创建的对象数组调用析构函数。

  • 如果我做 import const,那么对于每个常量,我必须将它称为 const.SOMETHING,这可能不是最方便的方法。
  • 在由 new []返回的指针上使用 delete或者在由 new返回的指针上使用 delete []会导致未定义行为。

    操作符 deletedelete []分别用于销毁用 newnew[]创建的对象,返回到分配给编译器内存管理器的剩余可用内存。

    作为测试,我创建了一个带有2个函数 A 和 B 的 test.py 模块,它们分别打印“ A1”和“ B1”。导入 test.py 之后:

    import test
    

    new创建的对象必须用 delete销毁,用 new[]创建的数组应该用 delete[]删除。

    Ng:

    from test import *
    

    在名称空间中没有对“ test”的引用,所以在编辑之后没有办法重新加载它(据我所知) ,这在交互式会话中是一个问题。鉴于以下任何一种情况:

    import test
    import test as tt
    

    我可以像 test.A ()和 test.B ()那样运行这两个函数,而“ test”在名称空间中显示为 模组,所以如果我编辑 test.py,我可以用以下方式重新加载它:

    import importlib
    importlib.reload(test)
    

    但如果我这么做:

    from test import *
    

    在名称空间中没有对“ test”的引用,所以在编辑之后没有办法重新加载它(据我所知) ,这在交互式会话中是一个问题。鉴于以下任何一种情况:

    import test
    import test as tt
    

    将在名称空间中添加“ test”或“ tt”(分别)作为模块名称,这将允许重新加载。

    将在名称空间中添加“ test”或“ tt”(分别)作为模块名称,这将允许重新加载。

    如果我这样做:

    from test import *
    

    如果我这样做:

    from test import *
    

    名称“ A”和“ B”在名称空间中显示为 功能。如果编辑 test.py 并重复上面的命令,则不会重新加载函数的修改版本。

    名称“ A”和“ B”在名称空间中显示为 功能。如果编辑 test.py 并重复上面的命令,则不会重新加载函数的修改版本。

    下面的命令将引发错误消息。

    importlib.reload(test)    # Error - name 'test' is not defined
    

    下面的命令将引发错误消息。

    importlib.reload(test)    # Error - name 'test' is not defined
    

    如果有人知道如何重新加载载有“从模块导入 *”的模块,请发帖。否则,这将是避免使用这种形式的另一个原因:

    from module import *
    

    对于 delete,如果传递的指针是实际对象类型的基类,则基类必须具有虚析构函数(否则,行为未定义)。如果它不是基类,则调用该类的析构函数,并使用该类或全局 operator delete中的 operator delete。如果传递了基类,则调用实际对象类型的析构函数,并使用在该类中找到的 operator delete,或者如果没有,则调用全局 operator delete。如果类中的 operator delete有第二个类型为 size_t的参数,它将接收要释放的元素数。

    所以在这种情况下我们需要使用 delete [] ptr

    这只是影响了我的整个视野..。

    绘制2个文本: 一个灰色(它将是阴影) ,并在它的顶部绘制第二个文本(y 坐标1px 多于阴影文本)。

    当我问这个问题时,我真正的问题是“这两者之间有区别吗?”?难道运行时不需要保存关于数组大小的信息,所以它就不能分辨出我们指的是哪个数组吗?”这个问题不会出现在“相关问题”中,所以只是为了帮助像我这样的人,这里有一个答案: “我们为什么还需要删除[]操作符呢?”

    数组的大小,那么它就不能分辨出我们指的是哪一个吗?”这个问题不会出现在“相关问题”中,所以为了帮助像我这样的人,这里有一个答案: “为什么我们甚至需要删除操作符?”

    C + + delete []运算符确保调用用 new []分配的所有对象的 Destructor。下面的示例演示了相同的。此外,当类具有非默认析构函数以释放获取的资源时,必须首选 delete [](如果之前使用了 new [])。否则,可能会导致内存泄漏。

    “从对象构造函数”< < num + + < < endl; }

    通用密码:-

    #include <iostream>
    using namespace std;
    
    
    class memTest{
    public:
    static int num;
    memTest(){
    cout<<"Constructor from object " << num++ << endl;
    }
    ~memTest(){
    cout<<"Destructor from object " << --num << endl;
    }
    };
    int memTest::num=0;
    
    ~ memTest (){

    示例1:-使用 new []和 delete 可能会导致未定义行为。

    int main() {
    memTest* Test1=new memTest[3];
        
    
    delete Test1; //<-----
    return 0;
    }
    
    Cout < < “ Destructor from object”< < —— num < < endl; }

    产出1:-

    Constructor from object 0
    Constructor from object 1
    Constructor from object 2
    Destructor from object 2 //<-----
    
    };

    示例2: 正确的行为是使用 new []和 delete []。

    int main() {
    memTest* Test1=new memTest[3];
        
    
    delete[] Test1; //<-----
    return 0;
    }
    
    Int memTest: : num = 0;

    示例1:-使用 new []和 delete 可能会导致未定义行为。

    int main() {
    memTest* Test1=new memTest[3];
        
    
    delete Test1; //<-----
    return 0;
    }
    

    产出2:-

    Constructor from object 0
    Constructor from object 1
    Constructor from object 2
    Destructor from object 2
    Destructor from object 1 //<-----
    Destructor from object 0 //<-----