【发布时间】:2013-04-22 08:20:05
【问题描述】:
距离我上一次用 C++ 做某事已经很多很多年了。这些天来,有人向我寻求 C++ 学校项目的帮助,我对我所见过的语言的一个“特性”很感兴趣,它运行良好,但我认为它不起作用。
我记得,我可以在堆上或堆栈上创建类的实例:
int main() {
MyClass *inHeap = new MyClass();
MyClass inStack = MyClass();
}
据我所知,第一个变量,inHeap,将使编译器在main 堆栈帧中保留一些堆栈,足以容纳一个指针(4 个字节?8 个字节? 类似的东西),它指向堆中对象的实际实例。
另外,第二个变量,inStack,将使编译器保留足够的堆栈以在main 堆栈帧中保存MyClass 的完整实例。
现在,我的问题。假设我有一个应该返回MyClass 实例的函数。一开始,我以为它只能返回堆中的实例:
MyClass *createInHeap() {
return new MyClass();
}
int main() {
MyClass* inHeap = createInHeap();
}
但我看到的是以下内容:
MyClass createInStack() {
MyClass c = MyClass();
return c;
}
int main() {
MyClass inStack = createInStack();
}
这里到底发生了什么?
MyClass实例的内存是否保留在createInStack的堆栈帧中?如果是这种情况,当函数createInStack返回时,这段代码是否会强制实例复制到main的堆栈帧中?这个拷贝是如何执行的,即它只是在main函数中为我自动调用了拷贝构造函数吗?我想到的另一种可能性是编译器足够聪明,已经为
main堆栈帧中的MyClass实例保留了内存。这存在吗?这是某种优化以避免制作可能昂贵的副本吗?
作为最后一个问题,当我在堆栈中创建了一个实例时,它的析构函数究竟是什么时候调用的?创建它的作用域何时结束?
【问题讨论】:
-
除非我遗漏了什么,否则您写的所有内容的答案都是“是”:)
-
注意,
MyClass c();确实不创建类MyClass的实例,而是声明了一个不带参数并返回类型为MyClass的对象的函数.MyClass inStack();也一样。 -
MyClass inStack();是一个函数声明;你的意思是MyClass inStack;。除此之外,答案几乎是“是”。 -
谢谢,伙计们。我修复了该函数调用与实例创建。
标签: c++ heap-memory allocation stack-memory