C++ 创建对象:使用或不使用“新建”`

C++ 创建对象:使用或不使用“新建”`,c++,constructor,new-operator,destructor,C++,Constructor,New Operator,Destructor,可能重复: 这可能是一个基本问题,可能已经被问过了(比如,);但我还是不明白。所以,让我问一下 考虑以下C++类: class Obj{ char* str; public: Obj(char* s){ str = s; cout << str; } ~Obj(){ cout << "Done!\n"; delete str; // See the commen

可能重复:

这可能是一个基本问题,可能已经被问过了(比如,);但我还是不明白。所以,让我问一下

考虑以下C++类:

class Obj{
    char* str;
public:
    Obj(char* s){
        str = s;
        cout << str;
    }
    ~Obj(){
        cout << "Done!\n";
        delete str;        // See the comment of "Loki Astari" below on why this line of code is bad practice
    }
};

为什么前者调用析构函数,而后者不调用(没有显式调用
delete


哪一个是首选的?

两者都做不同的事情

第一种方法创建具有自动存储持续时间的对象。它被创建、使用,然后在当前块(
{…}
)结束时超出范围。这是创建对象的最简单方法,与编写
intx=0时相同

第二种方法创建具有动态存储持续时间的对象,并允许两件事:

  • 对对象生命周期的精细控制,因为它不会自动超出范围;您必须使用关键字
    delete
    明确销毁它

  • 创建只有在运行时才知道大小的数组,因为对象是在运行时创建的。(这里我将不详细介绍分配动态数组的细节。)

两者都不可取;这取决于你在做什么,哪一个是最合适的

使用前者,除非你需要使用后者

<你的C++书应该很好地涵盖这一点。如果你没有,就不要再往前走了,直到你买了书,读了好几遍

祝你好运


您的原始代码已损坏,因为它
delete
s a
char
数组没有
new
。事实上,C样式字符串中没有新的
d;它来自一个字符串文本
delete
ing这是一个错误(尽管它不会生成编译错误,但会在运行时产生不可预测的行为)


通常,一个对象不应该负责
删除
它自己没有的东西
新建
。这种行为应该有很好的记录。在这种情况下,规则被完全破坏。

第一个分配了具有自动存储持续时间的对象,这意味着它将在退出定义它的范围时自动销毁


第二个分配了一个动态存储持续时间的对象,这意味着在明确使用<代码> Debug 之前,它不会被破坏。你看了那边的“相关”问题了吗?===>>>>>>>>当他们试图删除一个他们不拥有的指针时,这两个问题都是错误的。您不能删除从

“Hi there”
检索到的指针,即使它们拥有指针,类本身仍然会由于删除析构函数中的指针而被破坏,但编译器生成了复制构造函数和赋值运算符(违反了三者中的规则)。因此,该类的任何副本都意味着两个对象试图删除同一个指针。我希望您指的是
delete
,而不是
destroy
(不存在)。尚未提及,但
o1
可能具有静态或自动持续时间,这取决于程序中的位置。这一行出现。“自动存储持续时间”通俗地说是“在堆栈上”(因为这个存储通常是线程函数调用堆栈的一部分,并且在函数退出时被丢弃),而“动态存储持续时间”通俗地说是“在堆上”。@Mike:是的,我以天文数字般的热情轻视这些术语。我没有雇用他们是故意的;我是你最后一个看到传播这些不准确短语的人。”迈克:(我仍然明白,OP对连接有帮助,这是有用的,所以,谢谢。)@ YichuanWang:C++,就像其他编程语言一样,是抽象的。当你对一段C++代码进行合理化时,在抽象的上下文中这样做是有帮助的。将你的推理与特定的实现(例如,具有x86兼容CPU的计算机)捆绑在一起是不必要的限制,并且导致在C++标准定义的规则范围内缺乏严格性/可证明性。C++标准给出了存储持续时间的规则,而不是那些内存中的假设数据结构。乔恩,我想现在是Gooto列表。简洁,对我来说最好!
Obj o1 ("Hi\n");
Obj* o2 = new Obj("Hi\n");