创建一个对象:有或没有`new`

M.S*_*sti 119 c++ constructor destructor new-operator

可能重复:
使用new与without实例化对象之间有什么区别

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

考虑以下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
    }
};
Run Code Online (Sandbox Code Playgroud)

以下代码片段之间的区别是什么:

Obj o1 ("Hi\n");
Run Code Online (Sandbox Code Playgroud)

Obj* o2 = new Obj("Hi\n");
Run Code Online (Sandbox Code Playgroud)

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

哪一个更受欢迎?

Lig*_*ica 139

两者都做不同的事情.

第一个创建具有自动存储持续时间的对象.当前block({ ... })结束时,它被创建,使用,然后超出范围.这是创建对象的最简单方法,与编写时相同int x = 0;

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

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

  • 创建仅在运行时已知大小的数组,因为对象创建在运行时进行.(我不会在这里讨论分配动态数组的细节.)

两者都不是首选; 这取决于你在做什么是最合适的.

除非您需要使用后者,否则请使用前者.

你的C++书应该很好地涵盖了这一点.如果你没有,那么在你多次购买和阅读其中之一之前不要再进一步了.

祝好运.


您的原始代码已损坏,因为它不是delete一个char阵列new.事实上,没有什么 new是C风格的字符串; 它来自一个字符串文字.delete这是一个错误(虽然不会产生编译错误,但在运行时会产生不可预测的行为).

通常,一个对象不应该负责delete任何它本身不存在的东西new.这种行为应该有详细记录.在这种情况下,规则完全被打破.

  • "自动存储持续时间"通俗地称为"在堆栈上",(因为此存储通常是线程函数调用堆栈的一部分,并在函数退出时被丢弃),"动态存储持续时间"通俗地称为"在堆". (23认同)
  • @Mike:是的,我以天文般的热情鄙视这些条款.我故意没有雇用他们; 我是你见过传播那些不准确的短语的最后一个人. (4认同)
  • @Jon我猜[this](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)现在是首选名单. (4认同)
  • @YichuanWang:与其他编程语言一样,C++是_abstraction_.当您对一段C++代码进行合理化时,在该抽象的上下文中这样做很有帮助.将您的推理与某些特定实现(例如,具有x86兼容CPU的计算机)捆绑在一起是不必要的限制,并导致在C++标准定义的规则范围内缺乏严格性/可证明性.C++标准给出了关于_storage duration_的规则,而不是关于这些对象所在的内存中的某些假设数据结构. (2认同)

Jer*_*fin 20

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

第二个分配了一个具有动态存储持续时间的对象,这意味着在明确使用之前它不会被破坏delete.