我對C++中的範圍和內存管理有疑問。這是我遇到麻煩的情況:內存和範圍管理
Abc function f()
{
Abc c;
return c;
}
Abc d = f();
if(d) cout << "hi";
會說「hi」嗎?我的意思是...在f()中創建的Abc不是動態的(我們沒有寫一個新的)......但是我們正在返回值,所以我們獲得了對該對象的引用。它會有價值嗎?或者一旦它脫離了它的範圍,它就會死亡?
謝謝!
我對C++中的範圍和內存管理有疑問。這是我遇到麻煩的情況:內存和範圍管理
Abc function f()
{
Abc c;
return c;
}
Abc d = f();
if(d) cout << "hi";
會說「hi」嗎?我的意思是...在f()中創建的Abc不是動態的(我們沒有寫一個新的)......但是我們正在返回值,所以我們獲得了對該對象的引用。它會有價值嗎?或者一旦它脫離了它的範圍,它就會死亡?
謝謝!
#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)。
Abc f()
{
Abc c;
return c;
}
創建Abc
類型的c
,複製和從函數返回(帶NRVO
拷貝可以被消隱)。
Abc d = f();
if(d) cout << "hi";
創建d
與功能f
返回的值複製初始化。什麼是Abc
類型?如果它有operator bool
(或operator T()
,其中T
可以隱式轉換爲bool
) - 可能會打印「嗨」。
你的情況是不可能作出確切的聲明,在下面的第二種情況:
Abc* function f()
{
Abc *c = new Abc();;
return c;
}
Abc* d = f();
if(d) cout << "hi";
是的,它會說「你好」,所不同的是,在第一種情況下,c是保存在堆棧中,而在第二種情況下保存在堆棧中。在你的情況下,鍵入if(d)不是一個很好的方法來檢查對象是否存在,因爲它是在棧中定義的。
爲了檢查你的情況,你可以添加一個日誌到Abc的析構函數,看它是否會被擊中。當你用f()返回對象時,你會觀察到Abc的析構函數被調用。但這並不意味着物體已經死亡。只有它的析構函數被調用。但在這種情況下,你不能正確使用析構函數。這是選擇指向對象的指針的原因之一,而不是直接定義它們的原因之一。
你爲什麼不自己嘗試看看?如果在這裏撰寫和發佈問題,這會花費更少的時間。 – 2013-04-11 08:55:19
另外,「我們正在返回值」 - 是的,「所以我們保留對對象的引用」 - false。我在這裏沒有看到參考。 – 2013-04-11 08:56:21
只有在'Abc'可以轉換爲'bool'或者可以轉換爲bool的內建類型時纔會編譯。是這樣嗎? – juanchopanza 2013-04-11 08:58:06