我知道在Object creation on the stack/heap?中已经在SO中提出过很多问题 根据我的理解,如果一个对象存储在Stack中,如果变量超出范围,它将被弹出。但是当涉及到自动存储时,它会让我感到困惑,它是如何不在堆中的。我已经读过在C ++中使用new和delete不推荐(甚至邪恶是单词的选择),因为它会引入内存泄漏。所以我设置了像这样的测试代码
#include <iostream>
#include <string>
class Cat
{
public:
Cat(const std::string& name)
{
this->name = name;
std::cout << "construct Cat " << this->name << std::endl;
}
~Cat()
{
std::cout << "destruct Cat " << this->name << std::endl;
}
void feed()
{
std::cout << "feed Cat " << this->name << std::endl;
}
private:
std::string name;
};
Cat createFelix()
{
Cat garfield("Garfield");
Cat felix("Felix");
garfield.feed();
felix.feed();
return felix;
}
void getAndFeedFelix()
{
Cat justFelix = createFelix();
justFelix.feed();
}
int main()
{
getAndFeedFelix();
std::cout << "bla bla blah" << std::endl;
}
,结果就像这些
construct Cat Garfield
construct Cat Felix
feed Cat Garfield
feed Cat Felix
destruct Cat Garfield
feed Cat Felix
destruct Cat Felix
bla bla blah
所以在我的结论中,函数createFelix()
是从getAndFeedFelix()
调用的,它返回一个Cat(存储在堆栈中),它应该在函数返回后从堆栈弹出,但是对象由于自动存储机制,getAndFeedFelix()
超出范围后被破坏。怎么会发生这种情况?如果自动存储使用堆和引用计数,那么它可能是可能的。我的逻辑错了吗?
答案 0 :(得分:4)
您已发现Return Value Optimization(特别指定了返回值优化)。
此功能:
Cat createFelix()
{
Cat felix("Felix");
return felix;
}
Cat justFelix = createFelix();
看起来应该创建一个Cat
,复制它并销毁它。但作为优化,createFelix()
实际上会在felix
拥有的内存中创建justFelix
。所以我们只创建一个Cat
,没有副本。这里的一切都在堆栈上。
那么:
void getAndFeedFelix()
{
Cat justFelix = createFelix(); // creates a cat
justFelix.feed(); // feeds a cat
} // destroys a cat
您看到的输出是什么。