不同的实例化方式

时间:2011-11-19 23:30:31

标签: c++ pointers instantiation

我很好奇,有什么区别:

Trie* trie = new Trie();

Trie trie;

我想,在第一种情况下,trie只是第二种情况下指向对象的指针trie 对象本身。但实践中有什么不同?何时使用哪种方式?

或者,这些是“首选”风格吗?

3 个答案:

答案 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对象。