C ++对象存储在堆栈或堆中

时间:2015-01-15 03:14:09

标签: c++ oop stack heap

我知道在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()超出范围后被破坏。怎么会发生这种情况?如果自动存储使用堆和引用计数,那么它可能是可能的。我的逻辑错了吗?

1 个答案:

答案 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

您看到的输出是什么。