19.C++-(=)賦值操作符、初步編寫智能指針

(=)賦值操作符

  • 編譯器為每個類默認重載了(=)賦值操作符
  • 默認的(=)賦值操作符僅完成淺拷貝
  • 默認的賦值操作符和默認的拷貝構造函數有相同的存在意義

(=)賦值操作符注意事項

首先要判斷兩個操作數是否相等

返回值一定是 return *this; 返回類型是Type&型,避免連續使用=后,出現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;} };

?

注意:指針對象之間賦值是不會調用(=)復制操作符的

?

編譯器默認提供的類函數

包括了:構造函數,析構函數,拷貝構造函數, (=)賦值操作符

?

智能指針

智能指針的由來

在以前C程序里,使用malloc()等函數動態申請堆空間時,若不再需要的內存沒有被及時釋放,則會出現內存泄漏,若內存泄漏太多,則會直接導致設備停止運行,特別是嵌入式設備,可能有些設備一上電就要運行好幾個月.

在C++里,為了減少內存泄漏,所以便引出了智能指針

介紹

  • 智能指針實際上是將指針封裝在一個類里,通過對象來管理指針.
  • 構造函數時,通過對象將指針傳遞進來,指針可以是缺省值.
  • 然后構造-> ” “ * ” “ = 操作符重載,讓這個對象擁有指針的特性.
  • 最后通過析構函數,來釋放類里的指針.

?

注意

  • 智能指針只能指向堆空間中的對象或者變量
  • 并且一片空間最多只能由一個智能指針標識(因為多個指向地址相同的智能指針調用析構函數時,會出現bug)
  • ->和*都是一元操作符,也就是說不能帶參數

比如ptr->value的->:

當ptr的類型是普通指針類型時,等價于:(*ptr).mem

當ptr的類型是時,等價于:(ptr.operator->())->value ? ?等價于: ( *(ptr.operator->())?).value

所以->操作符函數的返回類型是type*,返回值是一個指針變量本身(不帶*)

具體參考: https://segmentfault.com/q/1010000004620896

?

接下來個示例,指向一個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; }

?

運行打印:

0
~Point()
1
~Point()
2
~Point()
3
~Point()
4
~Point()

?

從結果可以看到, Point p每被從新定義之前,便會自動調用析構函數來釋放之前用過的內存,

這樣便避免了野指針的出現

?

接下來,我們繼續完善上面代碼,使它能夠被賦值.

#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; //去掉const類型參數} return *this;}~Point(){cout<<"~Point()"<<endl;delete p;} };int main() { Point p=new int(2);Point p2;p2= p; //等價于 p2.operator= (p); cout <<"p=NULL:"<<p.isNULL()<<endl;*p2+=3; //等價于 *(p2.operator *())=*(p2.operator *())+3; //p2.operator *()返回一個int指針,并不會調用Point類的=操作符cout <<"*p2="<<*p2 <<endl;return 0; }

?

運行打印:

operator =()       p=NULL:1              // Point  p的成員已被釋放*p2=5~Point()
~Point()

但是,還有個缺點,就是這個智能指針僅僅只能指向int類型,沒辦法指向其它類型.?

接下來繼續修改,通過類模板來使這個智能指針能指向多種類型

#include <iostream>using namespace std;template <typename T>
class Point
{T *p;
public:Point(T *p){this->p = p; }bool isNULL(){return (p==NULL);}T* operator -> (){return p; } T& 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;   //去掉const類型參數
              }         return *this;}~Point(){delete p;    } };int main()
{       Point<int> p1=new int(2); cout<<*p1<<endl; Point<float> p2=new float(3.56);  cout<<*p2<<endl;return 0;
}

運行打印:

2
3.56
~Point()
~Point()

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452216.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452216.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452216.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows mysqldump 不成功 1049 1064 報錯

1064 路徑不對&#xff0c;需要cd選到mysql bin目錄下 1049 在cmd里面不需要分號 以下是正確的 E:\phpStudy\PHPTutorial\MySQL\bin>mysqldump -uroot -proot db >db.sql 轉載于:https://www.cnblogs.com/JANCHAN/p/9227388.html

學成在線--14.使用RabbitMQ完成頁面發布

文章目錄一.技術方案二.頁面發布——消費方1.需求分析2.創建Cms Client工程1&#xff09;創建maven工程2&#xff09;配置文件3&#xff09;啟動類3.RabbitmqConfig配置類4.定義消息格式5.PageDao1&#xff09;使用CmsPageRepository 查詢頁面信息2&#xff09;使用CmsSiteRepo…

對象模型中類與類間的關系

類與類之間通常有關聯、聚集、泛化(繼承)、依賴和細化4種關系 1.關聯 關聯表示兩個類的對象之間存在某種語義上的聯系。 (1) 普通關聯 只要在類與類之間存在連接關系就可以用普通關聯表示。普通關聯的圖示符號是連接兩個類之間的直線&#xff0c;如下圖所示。關聯…

記憶講師石偉華微信公眾號2017所有文章匯總(待更新)

17-10-24-不勝光榮的記憶 17-10-26-每日一個超長英文單詞&#xff08;2&#xff09; 17-10-27-每日一個超長英文單詞&#xff08;3&#xff09; 17-10-28-每日一個超長英文單詞&#xff08;4&#xff09; 轉載于:https://www.cnblogs.com/bakblog/p/9228096.html

Log4J日志配置詳解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、Log4j簡介 Log4j有三個主要的組件&#xff1a;Loggers(記錄器)&#xff0c;Appenders (輸出源)和Layouts(布局)。這里可簡單理解為日…

中文編碼雜談

編碼問題的例子 在windows自帶的notepad&#xff08;記事本&#xff09;程序中輸入“聯通”兩個字&#xff0c;保存后再次打開&#xff0c;會發現“聯通”不見了&#xff0c;代之以“”的亂碼。這是windows平臺上典型的中文編碼問題。即文件保存的時候是按照ANSI編碼&#xff…

Java NIO (十四)NIO 和 IO 的區別和適用場景分析

在研究Java NIO和IO API時&#xff0c;很快就會想到一個問題&#xff1a; 什么時候應該使用IO&#xff0c;什么時候應該使用NIO&#xff1f; 在本文中&#xff0c;我將嘗試闡明Java NIO和IO之間的區別&#xff0c;它們的用例以及它們如何影響代碼的設計。 ###Java NIO和IO之間的…

面向對象三種模型之間的關系

功能模型指明了系統應該“做什么”&#xff1b;動態模型明確規定了什么時候(即在何種狀態下接受了什么事件的觸發)做&#xff1b;對象模型則定義了做事情的實體。在面向對象方法學中&#xff0c;對象模型是最基本最重要的&#xff0c;它為其他兩種模型奠定了基礎&#xff0c;人…

android node

pkg install nodejs-current轉載于:https://www.cnblogs.com/insight0912/p/9231342.html

springmvc 中@Controller和@RestController的區別

1.Controller, RestController的共同點 都是用來表示Spring某個類的是否可以接收HTTP請求 2.Controller, RestController的不同點 Controller標識一個Spring類是Spring MVC controller處理器 RestController&#xff1a; a convenience annotation that does nothing more …

easyUI 日期控件修改...

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 個人覺得easyUI挺好用的。 它的中文文檔地址&#xff1a; http://www.zi-han.net/case/easyui/ 日期本來效果是這樣的&#xff1a; 改…

面向對象分析的三個模型與5個層次

在面向對象分析中&#xff0c;主要由對象模型、動態模型和功能模型組成。對象模型是最基本、最重要、最核心的。 面向對象建模得到的模型包含系統的3個要素&#xff0c;即靜態結構(對象模型)、交互次序(動態模型)和數據變換(功能模型)。解決的問題不同&#xff0c;這3個子模型…

學成在線--15.課程計劃查詢

文章目錄一.需求分析二.頁面原型1.tree組件介紹2.webstorm配置jsx三.API接口1.數據模型2.自定義模型類3.接口定義四.sql語句五.服務器端1.Dao1&#xff09;Mapper接口2&#xff09;Mapper映射文件2.Service3.Controller4.測試六.前端1.Api方法2.Api調用1&#xff09;定義查詢課…

團隊作業-項目答辯

1. 王書磊 1600802063 http://www.cnblogs.com/wsl-1117/ 劉令斌 1600802017 http://www.cnblogs.com/liulingbin/ 許浩然 1600802066 https://www.cnblogs.com/xuhaoran1/ 成明龍 1600802038 http://www.cnblogs.com/CMLCML/ 2這是我們的效果圖. 3.&#xff08;1&#xff09;修…

Java構造和解析Json數據的兩種方法詳解一

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在www.json.org上公布了很多JAVA下的json構造和解析工具&#xff0c;其中org.json和json-lib比較簡單&#xff0c;兩者使用上差不多但還是…

面向對象方法開發的方法

面向對象分析首要的工作&#xff0c;是建立問題域的對象模型。 這個模型描述了現實世界中的“類與對象”以及它們之間的關系&#xff0c;表示了目標系統的靜態數據結構。靜態數據結構對應用細節依賴較少&#xff0c;比較容易確定。因此&#xff0c;用面向對象方法開發絕大多數…

程序員編程需要多少個小時?

Michael Arrington曾發表一篇博文說&#xff0c;創業者必須加倍的努力工作&#xff0c;甚至不惜趴在辦公桌上睡覺&#xff0c;這樣才能成功。對此&#xff0c;我并不贊同其觀點&#xff0c;我看了很多評論都是關于這樣工作會適得其反&#xff0c;不但沒有獲得成功&#xff0c;相…

事務以及@Transcational注解

文章目錄1.事務的概念2.事務的四個特性3.關于Transcational注解的理解4.使用場景5.舉例6.編程式事務管理7.相關知識1.事務的概念 事務&#xff0c;是指作為單個邏輯工作單元執行的一系列操作&#xff0c;結果只有成功和失敗兩種&#xff0c;要么全部成功(全部提交)&#xff0c…

提高代碼復用率

由于現在的互聯網企業業務比較繁忙&#xff0c;導致產品狗不停地提需求&#xff0c;還總是改來改去&#xff0c;最后留給程序猿的時間少之又少。程序猿也不是吃素的&#xff0c;干脆直接copy一下代碼隨便搞一下實現功能就行&#xff0c;也談不上所謂的精心設計了。這樣的確是縮…

java 對 redis 的基本操作

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、server端安裝 1、下載https://github.com/MSOpenTech/redis 可看到當前可下載版本&#xff1a;redis2.6 2、安裝 1&#xff09;解壓…