[英]When does the anonymous objects get deleted from memory and when it is recommended to use them?
我是c ++的新手,我試圖理解構造函數和析構函數以及一些關於內存管理的內容。 在下面的代碼中,除了之外,一切都正常
1.MyClass()DISP(); 2.new MyClass; 3.new MyClass(300);
1)我想知道將所有這三個稱為匿名對象是否正確。 2)對於MyClass(),我知道這會創建一個對象並立即銷毀它,因此沒有內存問題。 但是對於新的MyClass(),析構函數永遠不會被調用。 我也明白,因為這是在堆上我將必須顯式刪除該對象。 但是在這種情況下我該怎么做?
如果不可能,程序執行后該內存何時可以釋放? 3)我也想知道這種類型的對象創建(新的MyClass)可能有用的場景。
#include<iostream>
#include<conio.h>
using namespace std;
class MyClass
{
private:
int num;
public:
MyClass()
{
cout<<"no-arg constructor"<<endl;
}
MyClass(int num)
{
this->num=num;
cout<<"one param constructor"<<endl;
}
~MyClass()
{
cout<<"inside destructor\t"<<num<<endl;
}
void disp()
{
cout<<num<<endl;
}
};
int main()
{
MyClass m1;
MyClass m2(200);
MyClass *m3=new MyClass;
MyClass *m4=new MyClass(400);
MyClass().disp();
new MyClass;
new MyClass(300);
delete m4;
delete m3;
return 0;
}
“匿名對象”不是標准術語,它是一個描述性術語。 我會把它解釋為沒有名字的對象。 具有名稱的對象稱為變量或數據成員。
在表達式MyClass().disp()
您在類MyClass
的臨時對象上調用成員函數disp
。 臨時對象的生命周期[1]延伸到完整表達式的末尾。 如果我沒記錯的話,在C ++標准中,它被稱為全表達式 。
new
-expression new MyClass
為新的MyClass
對象分配內存,並在該內存塊中創建一個新的MyClass
對象。 該表達式生成一個指向新對象的指針。 您可以將該指針存儲在變量中,並在稍后的delete
表達式中使用它來銷毀該對象並釋放其內存。
除了為MyClass
構造函數提供參數之外,表達式new MyClass(300)
是相同的。 new
的表達式語法還提供了一種表示法,用於指定分配操作的參數。 但這是更先進的,很少需要,無論如何,作為一個初學者,你應該優先從不使用原始的new
或delete
,而是標准的庫容器和字符串。
如果沒有相應的delete
new
對象,則該對象將一直存在,直到程序執行結束。 如果這是帶有操作系統的機器,那么操作系統將回收內存。 但是,操作系統對C ++對象一無所知,因此不會調用對象析構函數,因此不會執行析構函數中指定的清理。
你問new
的有用的地方。 通常,當對象的期望生命周期不適合作用域(本地自動變量的嵌套生存期)時,和/或需要動態大小對象的情況。 對於高效可移動的對象,使用new
來控制生命周期不像C ++ 11及更高版本那樣,而動態大小優先使用std::vector
等容器和std::string
等std::string
。
[1]更一般地說,臨時對象可以直接綁定到本地引用,在這種情況下,它的生命周期延長到引用的生命周期,即從封閉塊開始。
通常,您將在堆棧上分配對象,因為它更快,您不需要刪除它。
但是,如果要返回指針,則必須在堆上分配它。 例如
int *foo(int n)
{
int *pn = new int(n);
return pn;
}
現在調用者負責釋放內存。
int main()
{
try {
int *ptr = foo(6);
// use ptr
delete ptr;
} catch (std::bad_alloc &ba) {
std::cerr << ba.what() << '\n';
}
}
你的錯誤是不存儲new
的返回值。 如果不存儲返回值,您將如何使用內存? 你將如何釋放它? 這就像支付電影票,但然后把它扔出去。
你的程序有其他錯誤。 main
必須返回int
,而不是void
。 使用標准的getchar
函數而不是getch
也是一個更好的主意。
我還在代碼中添加了異常處理,因為new
在無法分配時拋出異常。 將整個main
函數代碼包裝在try
塊中是C ++代碼中常見的習慣用法。
除了干杯和hth。 - 阿爾夫的回答,我會加上這個......
如果你真的想要 並且 必須在堆上創建類Bar
的臨時對象,只需使用std :: make_shared (C ++ 11)或std :: make_unique (C ++ 14)....
例:
std::make_unique<Bar>()->foo()
std::make_shared<Bar>()->foo()
上面創建了Bar
並調用它的方法foo()
。 在foo()
完成后調用Bar
的析構函數,並且總是將其相關的內存刪除....
它可以編寫一個簡單的類和函數,就像在舊的C ++中一樣,但由於可變參數模板和完美的轉發 ,它不能是通用的
免費建議:避免任何需要上述情況的情況......即使下面的代碼(據說比堆更有效)通常在代碼審查中不受歡迎
Bar().foo()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.