詳解C++-(=)賦值操作符、智能指針編寫
(=)賦值操作符
- 編譯器為每個(gè)類默認(rèn)重載了(=)賦值操作符
- 默認(rèn)的(=)賦值操作符僅完成淺拷貝
- 默認(rèn)的賦值操作符和默認(rèn)的拷貝構(gòu)造函數(shù)有相同的存在意義
(=)賦值操作符注意事項(xiàng)
首先要判斷兩個(gè)操作數(shù)是否相等
返回值一定是 return *this; 返回類型是Type&型,避免連續(xù)使用=后,出現(xiàn)bug
比如:
class Test{
int *p;
Test(int i)
{
p=new int(i);
}
Test& operator = (const Test& obj)
{
if(this!=obj)
{
delete p;
p=new int(*obj.p);
}
return *this;
}
};
編譯器默認(rèn)提供的類函數(shù)
包括了:構(gòu)造函數(shù),析構(gòu)函數(shù),拷貝構(gòu)造函數(shù), (=)賦值操作符
智能指針
智能指針的由來
在以前C程序里,使用malloc()等函數(shù)動(dòng)態(tài)申請(qǐng)堆空間時(shí),若不再需要的內(nèi)存沒有被及時(shí)釋放,則會(huì)出現(xiàn)內(nèi)存泄漏,若內(nèi)存泄漏太多,
則會(huì)直接導(dǎo)致設(shè)備停止運(yùn)行,特別是嵌入式設(shè)備,可能有些設(shè)備一上電就要運(yùn)行好幾個(gè)月.
在C++里,為了減少內(nèi)存泄漏,所以便引出了智能指針
介紹
- 智能指針實(shí)際上是將指針封裝在一個(gè)類里,通過對(duì)象來管理指針.
- 在構(gòu)造函數(shù)時(shí),通過對(duì)象將指針傳遞進(jìn)來,指針可以是缺省值.
- 然后構(gòu)造“ -> ” “ * ” “ = ”等操作符重載,讓這個(gè)對(duì)象擁有指針的特性.
- 最后通過析構(gòu)函數(shù),來釋放類里的指針.
注意
- 智能指針只能指向堆空間中的對(duì)象或者變量
- 并且一片空間最多只能由一個(gè)智能指針標(biāo)識(shí)(因?yàn)槎鄠€(gè)指向地址相同的智能指針調(diào)用析構(gòu)函數(shù)時(shí),會(huì)出現(xiàn)bug)
- ->和*都是一元操作符,也就是說不能帶參數(shù)
比如ptr->value的->:
當(dāng)ptr的類型是普通指針類型時(shí),等價(jià)于:(*ptr).mem
當(dāng)ptr的類型是類時(shí),等價(jià)于:(ptr.operator->())->value 等價(jià)于: ( *(ptr.operator->()) ).value
所以->操作符函數(shù)的返回類型是type*,返回值是一個(gè)指針變量本身(不帶*)
接下來個(gè)示例,指向一個(gè)int型的智能指針
#include <iostream>
using namespace std;
class Point{
int *p;
public:
Point(int *p=NULL)
{
this->p = p;
}
int* operator -> ()
{
return p;
}
int& operator *()
{
return *p;
}
~Point()
{
cout<<"~Point()"<<endl;
delete p;
}
};
int main()
{
for(int i=0;i<5;i++)
{
Point p=new int(i);
cout <<*p<<endl;
}
return 0;
}
運(yùn)行打印:
0
~Point()
1
~Point()
2
~Point()
3
~Point()
~Point()
從結(jié)果可以看到, Point p每被從新定義之前,便會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)來釋放之前用過的內(nèi)存,這樣便避免了野指針的出現(xiàn)。
接下來,我們繼續(xù)完善上面代碼,使它能夠被賦值.
#include <iostream>
using namespace std;
class Point{
int *p;
public:
Point(int *p=NULL)
{
this->p = p;
}
bool isNULL()
{
return (p==NULL);
}
int* operator -> ()
{
return p;
}
int& operator *()
{
return *p;
}
Point& operator = (const Point& t)
{
cout<<"operator =()"<<endl;
if(this!=&t)
{
delete p;
p = t.p;
const_cast<Point&>(t).p=NULL;
}
return *this;
}
~Point()
{
cout<<"~Point()"<<endl;
delete p;
}
};
int main()
{
Point p=new int(2);
Point p2;
p2= p; //等價(jià)于 p2.operator= (p);
cout <<"p=NULL:"<<p.isNULL()<<endl;
*p2+=3; //等價(jià)于 *(p2.operator *())=*(p2.operator *())+3;
//p2.operator *()返回一個(gè)int指針,并不會(huì)調(diào)用Point類的=操作符
cout <<"*p2="<<*p2 <<endl;
return 0;
}
運(yùn)行打印:
operator =()
p=NULL:1 // Point p的成員已被釋放
*p2=5
~Point()
~Point()
但是,還有個(gè)缺點(diǎn),就是這個(gè)智能指針僅僅只能指向int類型,沒辦法指向其它類型.
總結(jié)
以上所述是小編給大家介紹的C++-(=)賦值操作符、智能指針編寫,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留
言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
解析C++無鎖隊(duì)列的實(shí)現(xiàn)代碼
本篇文章是對(duì)C++無鎖隊(duì)列的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C語(yǔ)言超詳細(xì)講解函數(shù)棧幀的創(chuàng)建和銷毀
我們知道c語(yǔ)言中函數(shù)都是被調(diào)用的,main函數(shù)里面能調(diào)用其他函數(shù),其實(shí)main函數(shù)也是被別的函數(shù)調(diào)用的,下面通過本文給大家分享c語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷毀過程,一起看看吧2022-05-05
C++使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序
ImGui?是一個(gè)用于C++的用戶界面庫(kù),跨平臺(tái)、無依賴,支持OpenGL、DirectX等多種渲染API,下面就跟隨小編一起學(xué)習(xí)一下如何使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序吧2023-08-08
C++實(shí)現(xiàn)LeetCode(769.可排序的最大塊數(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(769.可排序的最大塊數(shù)),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解
這篇文章主要介紹了C語(yǔ)言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
解決C語(yǔ)言數(shù)組元素循環(huán)右移的問題
今天小編就為大家分享一篇解決C語(yǔ)言數(shù)組元素循環(huán)右移的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
C/C++編程判斷String字符串是否包含某個(gè)字符串實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C++編程中判斷String字符串是否包含某個(gè)字符串的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11

