0

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

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

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

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

谢谢!

4

3 回答 3

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)编译。

于 2013-04-11T10:14:57.983 回答
1

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

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

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

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

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

于 2013-04-11T09:48:17.177 回答
0
Abc f() 
{
  Abc c;
  return c;
}

创建ctype Abc,复制它并从函数返回(NRVO可以省略复制)。

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

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

于 2013-04-11T08:56:38.143 回答