内存和范围管理

时间:2013-04-11 08:53:26

标签: c++ memory scope

我对c ++中的范围和内存管理存有疑问。这是我遇到麻烦的情况:

Abc function f() 
{
  Abc c;
  return c;
}

Abc d = f();
if(d) cout << "hi";

它会说“嗨”吗?我的意思是...在f()中创建的Abc不是动态的(我们没有写新的)...但是我们返回值,所以我们保留对该对象的引用。它是否有价值,或者一旦它超出其范围就会死亡?

谢谢!

3 个答案:

答案 0 :(得分:1)

在你的情况下,在下面的第二种情况下,不可能做出确切的陈述:

Abc* function f() 
{
   Abc *c =  new Abc();;
   return c;
}

Abc* d = f();
if(d) cout << "hi";

是的,它会说“hi”,不同之处在于,在第一种情况下,c保留在Stack中,而在第二种情况下,它保存在堆中。在您的情况下,键入if(d)不是检查对象是否存活的好方法,因为它是在堆栈上定义的。

为了检查你的情况,你可以在Abc的析构函数中添加一个日志,看看它是否会被命中。您将观察到当使用f()返回对象时,将调用Abc的析构函数。但这并不意味着物体已经死亡。只调用它的析构函数。但在这种情况下,您无法正确使用析构函数。这是选择指向对象的指针而不是直接定义它们的原因之一。

答案 1 :(得分:1)

#include <iostream>
using std::cout;
using std::endl;

class Abc
{
    int m_value = 0;
public:
    Abc()
    {
        cout << "Default Constructor" << std::endl;
    }

    Abc(const Abc& _source)
    {
        cout << "Copy Constructor" << std::endl;
        //copy stuff
    }

    Abc& operator=(const Abc& _source)
    {
        cout << "assignment operator" << std::endl;
        if (this == &_source)
            return *this;
        //copy stuff

        return *this;
    }

    Abc(const Abc&& _source)
    {
        cout << "Move Constructor" << std::endl;
        //move stuff
    }

    Abc& operator=(const Abc&& _source)
    {
        cout << "move assignment operator" << std::endl;
        //move stuff
        return *this;
    }

    ~Abc()
    {
        cout << "Destructor"<< std::endl;
    }

    void setValue(int _value)
    {
        m_value = _value;
    }

    int getValue()
    {
        return m_value;
    }
};

Abc f()
{
  Abc c;
  c.setValue(100);
  cout << "c value: " << c.getValue() << endl;
  return c;
}

int main()
{
    Abc d = f();
    cout << "d value: " << d.getValue() << endl;
    d.setValue(200);
    cout << "d value: " << d.getValue() << endl;
}

这是输出:

默认构造函数

c值:100

d值:100

d值:200

析构

从这里你可以看到编译器足够智能,可以重用已分配的对象而不需要任何哑副本(C ++ 98/03,C ++ 11相同的输出)。

与MinGW(GCC 4.7.1)一起编译。

答案 2 :(得分:0)

Abc f() 
{
  Abc c;
  return c;
}

创建c类型的Abc,复制它并从函数返回(可以省略NRVO副本。)

Abc d = f();
if(d) cout << "hi";

创建d并使用函数f的返回值对其进行复制初始化。什么是Abc类型?如果它有operator bool(或operator T()其中T可隐式转换为bool) - 可能会打印“hi”。