delete this 需要注意呀

來源:互聯網
上載者:User

首先轉載一下牛人的文章,我覺得寫得不錯:http://www.cppblog.com/lovedday/archive/2008/06/03/52060.html

內容如下:

In order to understand "delete this" :

First Step------dive into "delete p"

delete p 執行了哪兩個步驟?
delete p 是一個兩步的過程:調用解構函式,然後釋放記憶體。delete p產生的代碼看上去是這樣的(假設是Fred*類型的):

// 原始碼:delete p;
if (p != NULL) 
{
   p->~Fred();
   operator delete(p);
}

p->~Fred() 語句調用 p 指向的Fred 對象的解構函式。

operator delete(p) 語句調用記憶體釋放原語 void operator delete(void* p)。

Second Step-------"delete this"

成員函數調用delete this合法嗎?
只要你小心,一個對象請求自殺(delete this),是可以的。

以下是我對“小心”的定義:

你必須100%的確定,this對象是用 new分配的(不是用new[],也不是用定位放置 new,也不是一個棧上的局部對象,也不是全域的,也不是另一個對象的成員,而是明白的普通的new)。

你必須100%的確定,該成員函數是this對象最後調用的的成員函數。 

你必須100%的確定,剩下的成員函數(delete this之後的)不接觸到 this對象任何一塊(包括調用任何其他成員函數或訪問任何資料成員)。

你必須 100%的確定,在delete this之後不再去訪問this指標。換句話說,你不能去檢查它,將它和其他指標比較,和 NULL比較,列印它,轉換它,對它做任何事。 

自然,對於這種情況還要習慣性地告誡:當你的指標是一個指向基類類型的指標,而沒有虛解構函式時(也不可以 delete this)。

注意:因為是在類成員函數裡面delete this的,所以在此語句以後,不能訪問任何的成員變數及虛函數,否則一定非法。

我考慮到了另一種情況:如果父類有個成員函數DeleteMyself,專門做這種自殺行為,而子類沒有這個函數:

#include <iostream>
using namespace std;

class Animal
{
public:
Animal();
~Animal();
virtual void Shout();
void Name();
virtual void DeleteMyself();

private:
bool mbOld;
};

Animal::Animal():mbOld(false)
{
cout<<"Animal Born"<<endl;
}

Animal::~Animal()
{
mbOld = false;
cout<<"Animal time was gone!"<<endl;
}

void Animal::Shout()
{
cout<<"I am animal"<<endl;
}

void Animal::Name()
{
cout<<"My name is animal"<<endl;
}

void Animal::DeleteMyself()
{
delete this;
}

class Dog : public Animal
{
public:
Dog();
virtual ~Dog();
void Shout();
void Name();
};

Dog::Dog()
{
cout<<"Dog born"<<endl;
}

Dog::~Dog()
{
cout<<"Dog time was gone"<<endl;
}

void Dog::Shout()
{
cout<<"I am dog"<<endl;
}

void Dog::Name()
{
cout<<"My name is dog"<<endl;
}

void main()
{
Animal* pMyAnimal = new Dog;
pMyAnimal->Shout();
pMyAnimal->Name();
pMyAnimal->DeleteMyself();

cin.get();
}

那麼結果會是什麼樣子呢?父類的解構函式如果是虛函數會怎樣呢? 子類在記憶體中內否釋放乾淨呢?

首先看一下結果,父類的解構函式非虛,結果是:

Animal Born

Dog born

I am dog

My name is animal

Animal time was gone!

等於說:子類還是沒有釋放。

當父類的解構函式為虛時,結果是:

Animal Born

Dog born

I am dog

My name is animal

Dog time was gone

Animal time was gone!

那麼看來子類的解構函式是調用了,但是子類的記憶體釋放乾淨了嗎?

這裡我不敢肯定子類的記憶體釋放乾淨了,所以保險的做法是,在子類中重寫DeleteMyself。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.