簡體   English   中英

何時從內存中刪除匿名對象以及何時建議使用它們?

[英]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;

} 

“匿名對象”不是標准術語,它是一個描述性術語。 我會把它解釋為沒有名字的對象。 具有名稱的對象稱為變量或數據成員。

  1. 在表達式MyClass().disp()您在類MyClass臨時對象上調用成員函數disp 臨時對象的生命周期[1]延伸到完整表達式的末尾。 如果我沒記錯的話,在C ++標准中,它被稱為全表達式

  2. new -expression new MyClass為新的MyClass對象分配內存,並在該內存塊中創建一個新的MyClass對象。 該表達式生成一個指向新對象的指針。 您可以將該指針存儲在變量中,並在稍后的delete表達式中使用它來銷毀該對象並釋放其內存。

  3. 除了為MyClass構造函數提供參數之外,表達式new MyClass(300)是相同的。 new的表達式語法還提供了一種表示法,用於指定分配操作的參數。 但這是更先進的,很少需要,無論如何,作為一個初學者,你應該優先從不使用原始的newdelete ,而是標准的庫容器和字符串。

如果沒有相應的delete new對象,則該對象將一直存在,直到程序執行結束。 如果這是帶有操作系統的機器,那么操作系統將回收內存。 但是,操作系統對C ++對象一無所知,因此不會調用對象析構函數,因此不會執行析構函數中指定的清理。

你問new的有用的地方。 通常,當對象的期望生命周期不適合作用域(本地自動變量的嵌套生存期)時,和/或需要動態大小對象的情況。 對於高效可移動的對象,使用new來控制生命周期不像C ++ 11及更高版本那樣,而動態大小優先使用std::vector等容器和std::stringstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM