內存泄漏(C++主要的Bug來源)
1.動態(tài)申請堆空間,用完后不歸還
2.C++語言中沒有垃圾回收機制
3.指針無法控制所指堆空間的生命周期
代碼示例
創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為凌云等服務建站,凌云等地企業(yè),進行企業(yè)商務咨詢服務。為凌云企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。
#include <iostream>
#include <string>
using namespace std;
class Test
{
int i;
public:
Test(int i)
{
this->i = i;
}
int value()
{
return i;
}
~Test()
{
}
};
int main()
{
for(int i=0; i<5; i++)
{
Test* p = new Test(i);
cout << p->value() << endl;
}
return 0;
}
運行的結果如圖所示
可以看出輸出結果如預期一樣,但是指針在申請了內存之后沒有進行釋放,但當出現(xiàn)大量的數(shù)據(jù)時,程序會崩潰
智能指針的需求與目的
1.需要一個特殊的指針
2.指針生命周期結束時主動釋放堆空間
3.一片堆空間最多只能有一個指針標識
4.杜絕指針運算何指針比較
解決方案
1.重載指針特征操作符(->)
2.只能通過類的成員函數(shù)重載
3.重載函數(shù)不能使用參數(shù)
4.只能定義一個重載函數(shù)
代碼示例
#include <iostream>
#include <string>
//智能指針的實現(xiàn)
using namespace std;
class Test
{
int i;
public:
Test(int i)
{
cout << "Test(int i)" << endl;
this->i = i;
}
int value()
{
return i;
}
~Test()
{
cout << "~Test()" << endl;
}
};
class Pointer
{
Test* mp;
public:
Pointer(Test* p = NULL)
{
mp = p;
}
Pointer(const Pointer& obj)
{
mp = obj.mp;
const_cast<Pointer&>(obj).mp = NULL;
}
Pointer& operator = (const Pointer& obj)
{
if( this != &obj )
{
delete mp;
mp = obj.mp;
const_cast<Pointer&>(obj).mp = NULL;
}
return *this;
}
Test* operator -> ()
{
return mp;
}
Test& operator * ()
{
return *mp;
}
bool isNull()
{
return (mp == NULL);
}
~Pointer()
{
delete mp;
}
};
int main()
{
Pointer p1 = new Test(0);
cout << p1->value() << endl;
Pointer p2 = p1;
cout << p1.isNull() << endl;
cout << p2->value() << endl;
return 0;
}
運行的結果如圖所示
可以看到,指針在在對堆空間使用完之后,會自動釋放內存
小結
1.指針特征操作符可以被重載
2.重載指針特征符能夠使用對象代替指針
3.智能指針只能用于指向堆空間中的內存
4.智能指針的意義在于最大程度的避免內存問題
A.邏輯運算符的原生語義
1.操作數(shù)只有兩種值(true與false)
2.邏輯表達式不用完全計算就能確定最終值
3.最終結果只能是true或者false
代碼示例
#include <iostream>
#include <string>
using namespace std;
int func(int i)
{
cout << "int func(int i) : i = " << i << endl;
return i;
}
int main()
{
if( func(0) && func(1) )
{
cout << "Result is true!" << endl;
}
else
{
cout << "Result is false!" << endl;
}
cout << endl;
if( func(0) || func(1) )
{
cout << "Result is true!" << endl;
}
else
{
cout << "Result is false!" << endl;
}
return 0;
}
Q:邏輯操作符可以重載嗎?重載邏輯操作符有什么意義?
代碼示例及結果
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int v)
{
mValue = v;
}
int value() const
{
return mValue;
}
};
bool operator && (const Test& l, const Test& r)
{
return l.value() && r.value();
}
bool operator || (const Test& l, const Test& r)
{
return l.value() || r.value();
}
Test func(Test i)
{
cout << "Test func(Test i) : i.value() = " << i.value() << endl;
return i;
}
int main()
{
Test t0(0);
Test t1(1);
if( func(t0) && func(t1) )
{
cout << "Result is true!" << endl;
}
else
{
cout << "Result is false!" << endl;
}
cout << endl;
if( func(1) || func(0) )
{
cout << "Result is true!" << endl;
}
else
{
cout << "Result is false!" << endl;
}
return 0;
}
可以從代碼及運行結果可以看出,無論邏輯操作符是否更換兩端順序,都會對兩端數(shù)據(jù)進行運算
B.問題的本質分析
1.C++通過函數(shù)調用擴展操作符功能
2.進入函數(shù)體前必須完成所有參數(shù)的計算
3.函數(shù)參數(shù)的計算次序是不定的
4.短路法則完全失效
短路法則
a.(表達式1)&&(表達式2) 如果表達式1為假,則表達式2不會進行運算,即表達式2“被短路”
b.(表達式1)||(表達式2) 如果表達式1為真,則表達式2不會進行運算,即表達式2“被短路
建議:實際工程開發(fā)中避免重載邏輯操作符,通過重載比較操作符代邏輯操作符重載,直接使用成員函數(shù)代替邏輯操作符重載,使用全局函數(shù)對邏輯操作符重載
小結
1.C++從語法上支持邏輯操作符重載
2.重載后的邏輯操作符不滿足短路法則
3.工程開發(fā)中不要重載邏輯操作符
4.通過重載比較操作符替換邏輯操作符重載
5.通過專用成員函數(shù)替換邏輯操作符重載
網(wǎng)頁名稱:C++--智能指針、邏輯操作符的陷阱
網(wǎng)頁鏈接:http://jinyejixie.com/article0/gcioio.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、商城網(wǎng)站、手機網(wǎng)站建設、電子商務、虛擬主機、微信小程序
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)