我很好奇,有什么区别:
Trie* trie = new Trie();
和
Trie trie;
我想,在第一种情况下,trie
只是第二种情况下指向对象的指针trie
对象本身。但实践中有什么不同?何时使用哪种方式?
或者,这些是“首选”风格吗?
答案 0 :(得分:3)
这表明你需要从一本书开始认真学习C ++。这个问题的答案很长,因为这两个问题非常不同。
简而言之,这些是你的一些线索:
Trie* trie = new Trie();
在堆上分配内存,你得到一个指向已分配内存的指针,当你完成它时你需要delete
。
Trie trie;
在堆栈上分配trie
,一旦范围结束,对象就会被销毁。
如果您需要一个通过不同范围存活的对象,则使用第一个;如果仅在特定范围内需要该对象,则使用第二个。
第一个有运行时间成本,而第二个没有(或非常非常少)。
使用第一个,您可以分配所需的所有内存(尽可能多的RAM),而第二个则受到堆栈大小的限制。
加载程序时,操作系统为堆栈分配。编译器不会假设堆栈有任何特定的大小,事实上,在每次函数调用时或者一般情况下,当你进入e新范围时,只需在堆栈上进一步写入。如果您的递归函数太深,确实会出现分段错误(访问冲突)错误。
另一方面,堆是计算机拥有的整个内存池,操作系统管理。从操作系统调用new
请求内存。如果内存不足,操作系统可能会拒绝该请求,您将获得NULL
(旁注:每new
后,您必须检查结果是否为NULL
。如果是NULL
,你应该处理这个失败的情况。否则你的程序会崩溃)。同样,当不再需要内存时,必须 delete
。还要注意delete
调用对象的析构函数,因此对于理智的程序来说实际上是至关重要的。
答案 1 :(得分:1)
完全是关于生命的。
如果生命周期与其声明的生命周期相关联,那么第二个生命周期最有意义。如果生命周期更长,那么你通常使用前者(尽管你通常最好使用某种类型的shared_ptr以确保没有内存泄漏)。
e.g。如果我在函数或方法的持续时间内需要Trie:
void MyFun()
{
Trie trie;
// use my trie...
...
// now trie (instance of Trie) dies - no leaks, can't be accessed by anyone else, better not have given out pointers or references to it that exist beyond this point!!!
}
但也许我有一个类来容纳一个Trie(因此该实例将与它拥有类实例的生命周期相关联):
class C
{
public:
C() : trie(args..) { }
private:
Trie trie; // <- this instance will live exactly as long as it's instance of C does
};
但是,如果您需要Trie实例存在任意持续时间,或者拥有可变数量的使用者,那么您可以使用指针(或者如果Trie复制成本昂贵,或者保留外部资源或脆弱状态)。但这是一个更复杂的讨论,应该通过更长时间的基础C ++论文来处理。
答案 2 :(得分:0)
这是指向Trie
类的指针:Tire *trie;
此指针指向内存中未定义的位置,因为您尚未使用new为其分配内存地址。如果您尝试使用未定义的指针,它将导致异常并使您的程序结束(因为未定义的指针不指向任何东西)。当您使用语句:Trie *trie = new Trie();
时,您要求计算机分配足够的字节来保存堆上的一个Trie
对象,并将该内存地址返回到指针trie
。当您使用语句Trie trie;
时,您要求计算机分配足够的字节以在堆栈上保存一个Trie
对象。