C++中的内存管理
在C++中也是少不了對內(nèi)存的管理,在C++中只要有new的地方,在寫代碼的時候都要想著delete。 new分配的時堆內(nèi)存,在函數(shù)結(jié)束的時候不會自動釋放,如果不delete我分配的堆內(nèi)存,則會造成內(nèi)存泄露。所以我們要學(xué)會內(nèi)存管理,不要內(nèi)存泄露。在C++中的內(nèi)存管理機(jī)制和OC中的還不太一樣,在OC中的ARC機(jī)制會給程序員的內(nèi)存管理省不少事,但在C++中沒有ARC所以我們要自己管理好自己開辟的內(nèi)存。Java中也有自己相應(yīng)的內(nèi)存管理機(jī)制,比如JDBC里的獲取的各種資源在finally里進(jìn)行close等
那么什么情況下我們寫的程序會出現(xiàn)內(nèi)存泄露呢?下面我們將會舉一個簡單的例子來分析一下C++中的內(nèi)存管理機(jī)制。
1.建立一個測試類TestClass, TestClass類中有一個私有的屬性(指針類型),有一個無慘的構(gòu)造函數(shù),有一個析構(gòu)函數(shù),還有一個display方法用于輸出對象的信息
測試類的聲明如下:
在xxx.cpp文件中定義類的實現(xiàn)方法
實現(xiàn)構(gòu)造方法,實現(xiàn)構(gòu)造方法時要給屬性指針分配空間,不然的話屬性指針沒有分配內(nèi)存地址,調(diào)用時程序會崩潰,用new方法進(jìn)行堆分配
實現(xiàn)析構(gòu)函數(shù)在析構(gòu)函數(shù)中要對構(gòu)造函數(shù)中堆分配的內(nèi)存進(jìn)行delete,不然會造成內(nèi)存泄露
//析構(gòu)函數(shù) TestClass::~TestClass() {delete [] this->name;cout << "~TestClass()" << endl; }
實現(xiàn)display函數(shù),進(jìn)行name的打印測試
//描述方法 void TestClass::display() {cout << this->name <<endl; }
2. 在main函數(shù)中進(jìn)行測試
實例化對象時進(jìn)行堆分配:需要手動進(jìn)行內(nèi)存的釋放,不然也會造成內(nèi)存的泄露
實例化對象的棧分配:不需要手動釋放內(nèi)存,大括號結(jié)束時就自動釋放棧內(nèi)存
//棧分配,不用delete,出大括號后自動釋放TestClass stackClass = TestClass()
信息的打印輸出
testClass->display();
調(diào)用delete來釋放堆分配的對象
delete testClass;
3.程序運行結(jié)果:如果不加delete testClass; 析構(gòu)函數(shù)只會調(diào)用一個,因為堆分配的對象不會自動釋放,需要手動釋放,不加則會造成內(nèi)存的泄露
TestClass() TestClass() ludashi ~TestClass() ~TestClass()
4.拷貝構(gòu)造函數(shù)
如果在main函數(shù)中加入下面這句話,程序在運行時就會崩掉,如果要想程序正常運行可以把析構(gòu)函數(shù)中的delete [] this->name;注釋掉就可以運行。不過這樣會引起內(nèi)存的泄露。那么我們來研究一下為什么加上下面這句話程序會崩掉呢?原因是下那句話的意思是copyTest和stackClass指向同一塊棧內(nèi)存,當(dāng)其中一個調(diào)用析構(gòu)函數(shù)時就會把name給delete掉,另一個在析構(gòu)調(diào)用delete時就會報錯。怎么從基本上解決問題呢?接下來就是拷貝構(gòu)造函數(shù)出場的時候啦。
下面是拷貝構(gòu)造函數(shù)的定義方法
//拷貝構(gòu)造函數(shù) TestClass::TestClass(const TestClass &test) {//在堆中分配新的內(nèi)存this->name = new char[255];//進(jìn)行拷貝strcpy(this->name, test.name); }
在main函數(shù)中調(diào)用拷貝構(gòu)造函數(shù) ,這樣的代碼有不會有剛才的問題了
TestClass copyTest = stackClass;
5.再提內(nèi)存管理,不禁又想到初學(xué)C++那會的一句話“先構(gòu)造的后析構(gòu)”;有new的地方就得想著delete,為了避免內(nèi)存泄露。
? ?上面的拷貝構(gòu)造函數(shù)的作用是在聲明對象的時候可以利用拷貝構(gòu)造函數(shù)給新的對象賦值,如果像下面的這種情況就會出現(xiàn)過度釋放的問題; ?
? ?接下來就該操作符重載出場的時候了(operator = )把=號進(jìn)行重載
//對象之間的賦值:操作符重載 TestClass & TestClass :: operator = (const TestClass &test) {strcpy(this->name, test.name);return *this; }
總結(jié)
- 上一篇: iptables 状态策略 允许内网连接
- 下一篇: 【C++入门】简单的日期类操作