指針懸掛:
問題:使用new申請的內(nèi)存內(nèi)存空間無法訪問,也無法釋放。
原因:直接對指向new申請的存儲空間的指針變量進(jìn)行賦值修改
后果:失去了原來的地址,原來的空間無法訪問也無法釋放,造成內(nèi)存泄漏
還可能造成同一個(gè)內(nèi)存釋放兩次
容易引起指針懸掛的方式:對象的初始化和對象間賦值
容易引起指針懸掛的條件:類中含有指針類型的成員時(shí),使用默認(rèn)的拷貝構(gòu)造函數(shù)和賦值函數(shù)都會出現(xiàn)兩個(gè)指針變量互相賦值,產(chǎn)生指針懸掛的問題。
解決方法:需要重新定義拷貝構(gòu)造函數(shù)和超載賦值運(yùn)算符
賦值操作符:
作用:兩個(gè)已經(jīng)存在的對象間相互賦值,產(chǎn)生兩個(gè)完全相同的內(nèi)存拷貝
舉例:string a("hello");//調(diào)用構(gòu)造函數(shù)
string b("would");//調(diào)用構(gòu)造函數(shù)
string c=a;//調(diào)用拷貝構(gòu)造函數(shù)--風(fēng)格差,應(yīng)使用string c(a)
c=b; //調(diào)用拷貝賦值函數(shù)
重載賦值運(yùn)算符:
語法:
[html]
view plaincopyprint?X& X::operator=(const X & fm)
{
函數(shù)體
}
注意:
1、第一個(gè)引用的作用(為什么使用返回函數(shù)引用):
原因:為了實(shí)現(xiàn)對象間的連續(xù)賦值。
使用返回函數(shù)引用的好處:結(jié)果得到的是一個(gè)變量,它既可以當(dāng)左值,也可當(dāng)右值,且采用賦值時(shí)沒有引入臨時(shí)變量,直接從原結(jié)果拷貝。
2、第二個(gè)引用的作用:防止調(diào)用拷貝構(gòu)造函數(shù),因?yàn)榭截悩?gòu)造函數(shù)也可能引起指針懸掛
3、const的作用:當(dāng)參數(shù)使用引用時(shí),可能會改變傳入的參數(shù),為了避免這樣,就使用const
具體代碼:
[cpp]
view plaincopyprint?class Point
{
private:
char * name;
public:
Point(char * className)
{
name = new char[strlen(className)+1];
strcpy(name, className);
}
Point(const Point& p)//深拷貝
{
name = new char[strlen(p.name)+1];
strcpy(name,p.name);
}
~Point()
{
cout<<name<<endl;
delete []name;
}
Point& operator=(const Point&p);
};
系統(tǒng)自帶的等號運(yùn)算符:
Point& Point::operator=(const Point&p)
{
name=p.name;//造成指針懸掛
}
重載后的等號運(yùn)算符:
Point& Point::operator=(const Point&p)
{
delete[]name;//釋放原來的
name=new char[strlen(p.name)+1];
strcpy(name,p.name);
return *this;
}
拷貝構(gòu)造函數(shù)和重載賦值運(yùn)算符的代碼對比:
[cpp]
view plaincopyprint?Point::Point(const Point& p)//拷貝構(gòu)造函數(shù)
Point& Point::operator=(const Point&p)//重載賦值運(yùn)算符
注意:
1、參數(shù)都是一樣的,都有const和引用,但是帶他們的原因不同,具體見上面。
2、拷貝構(gòu)造函數(shù)無返回值,而重載賦值運(yùn)算符使用 返回函數(shù)引用。