自从我上次用 C++ 做某事以来已经有很多很多年了。这些天来,有人向我寻求 C++ 学校项目的帮助,我对我所见过的语言的一个“特性”很感兴趣,它运行良好,但我预计它不起作用。
我记得,我可以在堆上或堆栈上创建类的实例:
int main() {
MyClass *inHeap = new MyClass();
MyClass inStack = MyClass();
}
据我所知,第一个变量,inHeap
将使编译器在main
堆栈帧中保留一些堆栈,足以容纳一个指针(4 个字节?8 个字节?类似的东西),它指向对象的实际实例住在堆里。
此外,第二个变量,inStack
将使编译器保留足够的堆栈以在堆栈帧中保存MyClass
right的完整实例。main
现在,关于我的问题。假设我有一个函数应该返回一个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
?如果是这种情况,这段代码是否会强制将实例复制main
到函数createInStack
返回时的堆栈帧中?这个复制是如何执行的,即它只是在函数中自动为我调用复制构造main
函数吗?我想到的另一种可能性是编译器足够聪明,已经为堆栈帧
MyClass
中的实例保留了内存。main
这存在吗?这是某种优化以避免制作可能昂贵的副本吗?
最后一个问题,当我在堆栈中创建了一个实例时,它的析构函数究竟是什么时候调用的?创建它的范围何时完成?