簡體   English   中英

在析構函數C ++中刪除指針

[英]Deleting a pointer in destructor C++

我正在使用圖書館的課程。 讓它成為A,它有一個字符指針“token”

我的代碼:

void someFunction()
{
    A a;
    cout<<a.token;
    anotherFunction(a);
    cout<<a.token;  //  line 4: now token became invalid [1]
}

void anotherFunction(A copyOfA);
{
   //  doing something
}  //  on exit destructor of copyofA will be called

[1]為什么它變得無效:A類如下:

class A
{
    char *token;
    public:
    A()
    {
        token = GetRandomToken();   // GetRandomToken will return a 'new Char' array
    }
    ~A()
    {
        if(token != NULL)
        {
            delete[] token;    // it is A's responsibility to delete the memory it created
            token = NULL;
        }
    }
};

anotherFunction函數中,當anotherFunction的析構函數被調用時, token被刪除了。 所以在第4行,令牌無效,因為a.token和copyOfA.token都指向同一個地址。

在以下情況中,解決方案是什么:

情況1: class A在給定的庫中:所以我無法修改它。

案例2:如果我可以修改class A :處理這個問題的好方法是什么?

我知道,如果通過傳遞引用調用anotherFunction,我將不會遇到這個問題。 但是,如果我必須在某個時刻保留對象的副本呢?

在此處查看示例代碼: https//ideone.com/yZa4k4

如果你不能修改class A ,那么你應該避免復制它。 我認為最安全的方法是動態分配class A對象:

void anotherFunction(std::shared_ptr<A> aPtr)
{
    // please also note that in your case token is PRIVATE
    std::cout << aPtr->token << std::endl;
}

std::shared_ptr<A> aPtr(new A);
std::cout << aPtr->token << std::endl;
anotherFunction(aPtr);

或者,如果您堅持堆棧分配,則應將anotherFunction簽名更改為:

void anotherFunction(const A& a)
{
    std::cout << a.token << std::endl;
}

通過const引用傳遞你的參數(避免復制構造函數)。

現在,如果你可以修改你的class A ,你應該應用三/五/零的規則 ,因為你有非平凡的析構函數。 執行此操作的懶惰方法是將其他構造函數聲明為已刪除(然后,就像在您的示例中,您無法復制A對象,但您也可以保證沒有人會嘗試這樣做):

class A
{
    public:
    // for this example purpose I made token PUBLIC, but it is a bad idea in general
    char *token;
    A()
    {
        token = GetRandomToken();   // GetRandomToken will return a 'new Char' array
    }
    ~A()
    {
        if(token != NULL)
        {
            delete[] token;    // it is A's responsibility to delete the memory it created
            token = NULL;
        }
    }
    A(const A& other) = delete;
    A(A&& other) = delete;
};

或者,如果你不懶,你實際上可以考慮如何將內存從一個對象中的token指針復制到另一個對象 - 這取決於你如何實現它。 這取決於GetRandomToken的要求和實現。

如果您的示例是准確的,則class A沒有正確的復制構造函數,因此會刪除兩個實例的令牌。 這導致雙重刪除,因為第一個實例中的指針沒有改變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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