Creating an object: with or without `new`
Possible Duplicate:
What is difference between instantiating an object using new vs. without
这可能是一个基本问题,可能已经被问过(比方说,这里); 但我还是不明白。 所以,让我问一下。
考虑以下C ++类:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Obj{
char* str;
public:
Obj(char* s){
str = s;
cout << str;
}
~Obj(){
cout <<"Done!
";
delete str; // See the comment of"Loki Astari" below on why this line of code is bad practice
}
}; |
以下代码片段之间的区别是什么:
和
1 2
| Obj* o2 = new Obj("Hi
"); |
为什么前者调用析构函数,但后者不调用(没有显式调用delete)?
哪一个更受欢迎?
-
您使用的是哪本C ++教科书? 你看过那边的"相关"问题======= >>>>>>
-
两者都是borken,因为他们尝试删除他们不拥有的指针。 您无法删除从"Hi there"检索到的pointe
-
即使它们拥有指针,由于删除了析构函数中的指针,类本身仍然会被破坏,但是编译器生成了复制构造函数和赋值运算符(违反了规则)。 因此,该类的任何副本都意味着两个对象试图删除相同的指针
-
我希望你的意思是delete而不是destroy(它不存在)。
-
尚未提及,但o1可能具有静态或自动持续时间,具体取决于此行发生的程序中的位置。
两者都做不同的事情。
第一个创建具有自动存储持续时间的对象。当前块({ ... })结束时,它会被创建,使用,然后超出范围。这是创建对象的最简单方法,与编写int x = 0;时的方法相同
第二个创建一个具有动态存储持续时间的对象,并允许两件事:
两者都不是首选;这取决于你在做什么是最合适的。
除非您需要使用后者,否则请使用前者。
你的C ++书应该很好地涵盖了这一点。如果你没有,那么在你多次购买和阅读其中之一之前不要再进一步了。
祝好运。
您的原始代码已损坏,因为delete是一个char的数组,它不是new。事实上,没有什么new d C风格的字符串;它来自一个字符串文字。 delete这是一个错误(虽然不会产生编译错误,但在运行时会产生不可预测的行为)。
通常一个对象不应该负责delete任何它本身不是new的东西。这种行为应该有详细记录。在这种情况下,规则完全被打破。
-
"自动存储持续时间"通俗地称为"在堆栈上",(因为此存储通常是线程函数调用堆栈的一部分,并在函数退出时被丢弃),"动态存储持续时间"通俗地称为"在堆"。
-
@Mike:是的,我以天文般的热情鄙视这些条款。我故意没有雇用他们;我是你见过传播那些不准确的短语的最后一个人。
-
@Mike :(尽管如此,我知道OP可能有助于了解连接;所以,谢谢你。)
-
我发布它们是因为它们是白话,而Sadeq会看到它们。就这样。我也不关心它们,但我使用它们,因为我通常必须记录嵌入式系统,你确实需要知道堆栈上是否有东西。
-
@Mike:*点头*
-
@LightnessRacesinOrbit请您详细说明为什么"在堆栈上"不准确?
-
@YichuanWang:与其他编程语言一样,C ++是一种抽象。当您对一段C ++代码进行合理化时,在该抽象的上下文中这样做很有帮助。将您的推理与某些特定实现(例如,具有x86兼容CPU的计算机)捆绑在一起是不必要的限制,并导致在C ++标准定义的规则范围内缺乏严格性/可证明性。 C ++标准给出了有关存储持续时间的规则,而不是关于这些对象所在的内存中的某些假设数据结构。
-
@YichuanWang :(续)说实话,当你在堆栈上有struct T { int x; }; T* p = new T(); Is p->x"这样的代码时,它会导致人们弄错了?"不,但很多人会说"是"。如果我问它是否有"自动存储持续时间",那么你更倾向于发现答案仍然没有。
-
因为对象创建发生在运行时,意思是什么?使用new确保在运行时创建对象吗?如果是这样,那么何时在不使用new的情况下创建对象?
-
@Cupidvogel:是的。如果没有new,编译器生成的代码会为烘焙到它的对象留出空间。请记住,汇编与C ++不太相似:事实上,您的对象在可执行文件中很明显,只是因为各种算术都知道堆栈帧中特定"位置"处存在对象。默认情况下,对象的存在基本上是"硬编码的"。
-
@LightnessRacesinOrbit我很欣赏这个答案是4年了,但答案中的"其中一个"[jcatki.no-ip.org/fncpp/Resources]的链接现在已经破了,这很遗憾因为我非常热衷于购买你的一个推荐!
-
@Jon我想这是现??在的首选名单。
第一个分配具有自动存储持续时间的对象,这意味着它将在退出定义它的范围时自动销毁。
第二个分配了一个具有动态存储持续时间的对象,这意味着在明确使用delete之前,它不会被破坏。