我注意到,有两种方法可以创建C++对象:创建C++对象
BTree *btree = new BTree;
和
BTree btree;
从我所知道的,唯一不同的是类对象是如何访问( 。 - > - >运算符),并且当使用第一种方法时,私有整数被初始化为0.
哪种方式更好,有什么区别?
你怎么知道什么时候使用一个或另一个?
我注意到,有两种方法可以创建C++对象:创建C++对象
BTree *btree = new BTree;
和
BTree btree;
从我所知道的,唯一不同的是类对象是如何访问( 。 - > - >运算符),并且当使用第一种方法时,私有整数被初始化为0.
哪种方式更好,有什么区别?
你怎么知道什么时候使用一个或另一个?
好吧,它们被储存在不同的记忆区域。
这是一个很好的阅读。 Heap and Stack
我对堆和堆栈有所了解。为什么我会在乎它放在哪里?我什么时候需要它在堆中,什么时候我需要它在堆栈中? – neuromancer 2010-05-02 00:56:09
堆栈在应用程序中受到限制。堆没有限制(虚拟内存空间)。堆栈也受限于变量的范围。堆允许您传递结构而不考虑范围。 – 2010-05-02 00:57:46
这种说法是错误的。请不要忽略静态内存。例如。全局(或命名空间范围)中的'BTree btree;'语句在静态内存中创建对象,这可能很有意义,特别是在内存受限的环境中(所有那些自动内存管理的语言,如Java *咳嗽*似乎都是盲目的我们..)。 – Frunsi 2010-05-02 01:13:59
第一种形式在堆上创建对象,而第二种形式在堆上创建对象。
当功能完成运行时,第二个将被销毁。 第一个将保持活着,直到被删除。
如果您只想使用当前范围内的对象,则第二种形式最好。你不必担心摆脱它,因为它会为你完成。另请注意,如果在堆栈上创建了类,某些库不起作用。
如果对象应该超过该功能,则新窗体是更好的选择。
两个差异:
它们在存储器中创建的不同部分中的对象(堆VS堆栈)
对象寿命是不同的: 在第一种情况中,代码管理内存分配明确,,它也必须明确地管理取消分配(使用删除/删除[])。
在第二种情况下,该对象被自动地在其闭合范围的端部释放(或者一种方法,一种方法内的嵌套块,或一类),你使用哪一个
主要取决于在对象的生命周期中(如果它应该超过创建它的方法)。
+1,我只想添加第一条和简单的经验法则:喜欢自动分配,在需要时使用显式分配,例如,一个坏例子:'void foo(){BTree * btree = new BTree; btree-> DoSomething的();删除btree; }' – Frunsi 2010-05-02 01:08:56
如果该对象在main中声明,当两个方法的main都退出时它会自动被释放吗? – neuromancer 2010-05-02 01:32:28
在程序结束之前未被删除的堆分配对象(使用'new')本身不会被“解除分配”。例如,它的析构函数将不会因程序结束而被调用。但是,该对象使用的内存将返回到操作系统。在现代操作系统下运行的程序无法在退出后继续使用内存,无论它有多严重的泄漏。 – 2010-05-02 01:50:53
高级别区别是对象生存期。例如,如果您正在编写视频游戏,您将通过new
分配与堆上的怪物对应的对象。这样,怪物的基础物体就像怪物一样生活,这在编写程序时是不可知的。当玩家杀死怪物时,你的代码可以使用delete
销毁怪物物体。
另一方面,您将使用另一种形式的总分计数器,因为您知道计数器需要多长时间(大概只要游戏正在运行!)。通过将这种形式放在任何函数体外的“全局范围”中,它将被静态分配,作为程序二进制本身的一部分。
最后,如果你计算数组的总和,是这样的:
int mysum(int* arr, int len) {
int sum = 0;
for (int i = 0; i < len; ++i) { sum += arr[i] }
return sum;
}
的sum
变量堆栈,这基本上是你想要什么就分配:你不要临时变量必须显式释放,并且只在该函数实际运行时才会执行。
这两种形式的另一个区别是分配这些对象的存储时间。表格BTree bTree;
命名为静态分配,其分配在编译时完成 - 即编译器将在运行时为内存中的此对象安排内存空间。而所谓的动态分配BTree *pbTree = new BTree
的分配 - 在运行时执行 - 即只有当正在运行的程序到达此点时才会分配momory。
在这种情况下,静态和动态分配之间的差异并不明显。考虑以下情况:需要为整数数组分配内存空间,但是只能在运行时确定元素的数量,即我们只能知道程序开始执行后数组所占用的确切内存空间。
// in this function, we want to return a copy of the parameter array
int *array_cpy(int *arr, int num){
int *copy = new int[ num ];
int i;
for(i = 0; i < num; i++){
copy[ i ] = arr[ i ];
}
return copy;
}
这里定义int copy[ num ];
是不恰当的,其中一个原因是我所上述,另一种是copy
寿命活得比的功能。但是,鉴于最近的语言规范允许VLA,第二个原因是这个问题的关键。
在你是应该堆栈还是堆分配内存之间进行选择时,你需要仔细研究两者之间的差异。
是的,堆栈内存具有在超出范围时自动释放的优点,但通过智能指针和堆分配也可以实现同样的效果。更重要的是为什么发生这种情况的原因。
性能: 堆栈内存被自动清除,因为它涉及内存超出范围时栈指针的简单移位。由于这个原因,堆栈内存的分配和释放比堆内存快得多。
内存使用期限: 堆分配内存超出了分配函数的范围。堆栈不是。从上面关于调整堆栈指针的推理出发,一旦内存被解除分配,它是空闲的并且很可能被覆盖以用于下一个堆栈分配。
简而言之,当分配是临时的时候使用堆栈内存,特别是如果您需要重复分配并且性能很重要。当对象需要超出分配方法时使用堆内存。
请参阅此处了解有关堆栈和堆栈的信息:http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap,http://stackoverflow.com/questions/ 408670/stack-static-and-heap-in-c – 2010-05-02 00:59:20