C++入門系列-賦值運算符重載

🌈個人主頁:羽晨同學?

💫個人格言:“成為自己未來的主人~”??

賦值運算符重載

運算符重載

C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數名的函數,也具有其返回值類型,函數名字以及參數列表,其返回值類型和參數列表與普通的函數類似。

?函數名字為:關鍵字operator后面接需要重載的運算符符號。

函數原型:返回值類型operator操作符(參數列表)

注意:

  • 不能通過連接其他符號來創建新的操作符,比如operator@,這個其實完全沒意義。
  • 重載操作符必須有一個類類型參數,這個就證明了重載操作符是針對自定義類型的,不可能針對內置類型。
  • 用于內置類型的運算符,其含義不能改變,例如:內置的整型+,不能改變其含義。
  • 作為類成員函數重載時,其形參看起來比操作數少一,因為有一個隱藏的this指針。
  • .*? ?::? sizeof? ?:? ?.這五個運算符是不能重載的。

接下來我們先來講講這五個不能重載的運算符中的第一個。這個運算符是極其少見的。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class OB
{
public:void func(){cout << "void func()" << endl;}
};
typedef void(OB::* PtrFunc)();int main()
{PtrFunc fp = &OB::func;//成員函數取地址要加一個&,普通函數函數名就是地址OB temp;(temp.*fp)();return 0;
}

其實.*的作用是什么呢,我們可以通過這段代碼看到,.*的作用就是幫助我們調用成員函數的指針。

?接下來,我們就回到了operator關鍵字的作用,這個關鍵字可以極大的提高代碼的可讀性,我們來看下面的代碼。

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}
void Test()
{Date d1(2018,9.26);Date d2(2018, 9, 27);cout << (d1 == d2) << endl;
}

這段代碼是operator的全局調用,我們會看到如果全局調用的話會存在一個問題,那就是成員變量是私有的。我們無法保證封裝性。

這里的解決辦法有三種,

  1. ?提供這些成員的get和set
  2. 友元?
  3. 重載為成員函數

我們一般使用的就是第三種。重載為成員函數

什么意思呢?我們來看下面的這段代碼

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}bool Func(const Date& d){return this->_year == d._year&& this->_month == d._month&& this->_day == d._day;}bool operator==(const Date& d){return this->_year == d._year&& this->_month == d._month&& this->_day == d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d3(2024, 4, 14);Date d4(2024, 4, 15);cout << d3.operator==(d4) << endl;cout << (d3 == d4) << endl;return 0;
}

?懂了嗎,我們將重載函數放到成員函數里面,就避免了權限不夠的問題。

賦值運算符重載

賦值運算符重載格式

  • 參數類型:const T&,傳遞引用可以提高傳參效率。
  • 返回值類型: T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續復制
  • 檢測是否自己給自己復制
  • 返回*this,要復合連續賦值的含義。
#include<iostream>
using namespace std;class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){cout << "	Date(const Date& d)" << endl;_year = d._year;_month = d._month;_day = d._day;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}~Date(){cout << "~Date()" << endl;_year = -1;_month = -1;_day = -1;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 4, 14);Date d2(d1);Date d3 = d1;return 0;
}

?2.賦值運算符只能重載成類的成員函數不能重載成全局函數

這個怎么理解呢?其實重載成類的成員函數和重載成全局函數有一個很大的不同點,就是成員函數還有一個潛在的this指針,而全局函數是沒有這個東西,所以,如果要重載為全局函數的話,我們就需要給兩個參數。

class Date
{
public:Date(int year = 1949, int month = 10, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};Date& operator=(Date& left, const Date& right)
{if (&left != &right){left._year = right._year;left._month = right._month;left._day = right._day;}return left;
}

我們發現這個代碼是會報錯的,?原因是由于賦值運算符如果不顯示實現,編譯器會生成一個默認的。此時用戶再在類外自己實現一個全局的賦值運算符重載,就和編譯器在類中編譯器自己生成的默認賦值運算符重載沖突了,故賦值運算符重載只能是類的成員函數。

用戶沒有顯示實現時,編譯器會生成一個默認賦值運算符重載,以值的方式逐字節拷貝,注意:內置類型成員變量是直接賦值的,而自定義類型變量是需要調用對應類的賦值運算符重載完成賦值。

class Date
{
public:Date(int year = 2024, int month = 3, int day = 4){_year = year;_month = month;_day = day;}
private:int _month;int _day;int _year;
};
int main()
{Date d1(2024, 5, 15);Date d2;d2 = d1;return 0;
}
#include<iostream>
using namespace std;
class Time
{
public:private:int _hour = 1;int _second = 1;int _minute = 1;
};
class Date
{
public:void Print(){cout << "class Time" << endl;}Date(int year = 2024, int month = 3, int day = 4){_year = year;_month = month;_day = day;}
private:int _month;int _day;int _year;Time _t;
};
int main()
{Date d1(2024, 5, 15);Date d2;d2 = d1;d1.Print();d2.Print();return 0;
}

?

通過這個結果,我們可以很明顯的得出上面的結論。

?

?

?

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

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

相關文章

使用React.createContext()在React應用中傳遞數據,nolan出品

React.createContext() 是React中的一個API&#xff0c;用于創建一個“上下文”&#xff0c;這是一種在組件樹中傳遞數據的方法&#xff0c;而無需手動將props逐級傳遞。 這個方法接受一個參數&#xff0c;即默認值&#xff0c;當組件在樹中上層沒有找到對應的Provider時&…

【GESP試卷】2024年03月Scratch三級試卷

2024年GESP03月認證Scratch三級試卷 分數&#xff1a;100 題數&#xff1a;27 一、單選題(共15題&#xff0c;每題2分&#xff0c;共30分) 010203040506070809101112131415CBACADDADCBCBAB 1、小楊的父母最近剛剛給他買了一塊華為手表&#xff0c;他說手表上跑的是鴻蒙&…

24長三角A題思路+分析選題

需要資料的寶子們可以進企鵝獲取 A題 問題1&#xff1a;西湖游船上掉落華為 mate 60 pro 手機 1. 手機掉落范圍分析 物品特征&#xff1a;華為 mate 60 pro 手機的尺寸、重量、形狀等特性。靜水假設&#xff1a;西湖水面平靜&#xff0c;不考慮水流影響。掉落位置&#xff…

在C#語言里對NULL的技術處理

文章目錄 前言1 、NULL合并操作符&#xff08;??&#xff09;2. 條件運算符 (?:)3. 空條件運算符(?.)4. 空合并賦值操作符 (??)5. 寬容運算符 (!.)6. 使用 is 運算符7. ArgumentNullException 參數空異常結論 前言 在 C# 中&#xff0c;null 是一個特殊存在&#xff0c;…

安卓Fragment基礎

目錄 前言一、基礎使用二、動態添加Fragment三、Fragment的生命周期四、Fragment之間進行通信五、Fragment兼容手機和平板示例 前言 Fragment基礎使用筆記 一、基礎使用 Activity布局和文件 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/andro…

OpenAI 發布 GPT-4o,再次鞏固行業地位!

5 月 14 日凌晨 1 點&#xff08;太平洋時間上午 10 點&#xff09;&#xff0c;OpenAI 發布了其最新的 GPT-4o&#xff0c;再次鞏固了其在人工智能領域的領導地位。這次發布不僅僅是一個產品的推出&#xff0c;更是向世界宣告 AI 技術已邁入一個全新的紀元。OpenAI 的 CEO 薩姆…

品牌竄貨治理管控的方法

竄貨問題確實是一個需要品牌方高度關注和有效治理的難題。這種現象通常源于品牌區域銷售政策的差異&#xff0c;經銷商為了獲取更多的利潤&#xff0c;往往會利用這些差異進行跨區域的低價銷售。這不僅損害了大多數經銷商的利益&#xff0c;也破壞了市場的穩定和品牌價值。 品牌…

深入理解 Spring 循環依賴之三級緩存(附源碼分析)

前言&#xff1a; 學過 Spring 的都知道 Spring 利用三級緩存解決了循環依賴問題&#xff0c;那你知道什么是循環依賴&#xff1f;什么又是三級緩存&#xff1f;本篇將從源碼層面分析 Spring 是怎么去利用三級緩存幫我們解決循環依賴問題。 深入理解 Spring IOC 底層實現機制…

三生隨記——麗水詭事

在浙江的深山之中&#xff0c;隱藏著一座名為麗水的古老小城。這里山水秀麗&#xff0c;風景如畫&#xff0c;但在這美麗的外表下&#xff0c;卻隱藏著不為人知的恐怖秘密。 傳聞&#xff0c;麗水的郊外有一片被詛咒的竹林。這片竹林與其他竹林不同&#xff0c;它的葉子常年枯黃…

c# datagridview基本操作,包括行拖拽,添加自定義行列。

項目場景&#xff1a; 這段代碼定義了一個名為 ucDatagridviewHelper 的用戶控件&#xff08;UserControl&#xff09;&#xff0c;該控件包含了一個 DataGridView 控件和一些其他功能。 這段代碼的主要部分&#xff1a; 構造函數&#xff1a;在構造函數中&#xff0c;初始化…

C++ | Leetcode C++題解之第89題格雷編碼

題目&#xff1a; 題解&#xff1a; class Solution { public:vector<int> grayCode(int n) {vector<int> ret(1 << n);for (int i 0; i < ret.size(); i) {ret[i] (i >> 1) ^ i;}return ret;} };

數據結構--紅黑樹(RBTree)

一、紅黑樹概念 1.1 什么是紅黑樹 紅黑樹&#xff0c;是一種二叉搜索樹&#xff0c;但在每個結點上增加一個存儲位表示結點的顏色&#xff0c;可以是Red或 Black。 通過對任何一條從根到葉子的路徑上各個結點著色方式的限制&#xff0c;紅黑樹確保沒有一條路徑會比其他路徑長…

openEuler-22.03-LTS安裝opengauss5.0.1(包含cm集群管理)主備

環境說明 openEuler-22.0.3-LTS opengauss5.0.1 安裝數據庫 安裝系統依賴包 yum -y install lksctp* yum -y install psmisc yum -y install bzip2 yum -y install unzip yum -y install gcc yum -y install gcc-c yum -y install perl yum -y install libxml2-devel yum …

前端(包含cocosCreator)開發環節調取后端接口時跨域,解決辦法之反向代理

/** eslint-disable */ var http require(http),httpProxy require(http-proxy),HttpProxyRules require(http-proxy-rules);// Set up proxy rules instance var port 9090 var proxyRules new HttpProxyRules({rules: {/api/(.*): https://baidu.com/$1, // 測試環境游戲…

自學VBA 設置單元格文字格式 筆記

一.設定對應單元格對應需要顯示的格式 Cells(1, 1).Font.Size 18 字體大小 Cells(1, 2).Font.Color RGB(255, 0, 0) 字體顏色 Cells(1, 3).Font.Name "黑體" 字體類型 Cells(1, 4).Font.Italic True 字體斜體 Cells(1, 5).Font.FontStyle "BOLD"…

ubuntu下gcc編譯器的安裝

.gcc編譯器的安裝 一般linux下是覆蓋含有的&#xff0c;如果沒有執行更新命令 sudo apt update gcc安裝成功&#xff0c;可以檢查一下版本 可以看出我的gcc是9.4.0版本的

驗證torch.nn.Conv2d

import os import cv2 import torch import numpy as np import random import cv2 as cv from matplotlib import pyplot as pltdef f_VerifyConv2D():"""驗證torch.nn.Conv2d&#xff0c; 并將輸入數據及權重保存到txt文件中"""x torch.randn…

SpringBoot環境隔離Profiles

前言 通常我們開發不可能只有一個生產環境&#xff0c;還會有其它的開發&#xff0c;測試&#xff0c;預發布環境等等。為了更好的管理每個環境的配置項&#xff0c;springboot也提供了對應的環境隔離的方法。 直接上干貨 知識點 激活環境方法 1&#xff0c;在application…

專用設備制造業供應商收發文件,有什么專業而輕便的方式嗎?

專用設備制造業的特點包括&#xff1a;門類廣、跨度大、科技含量高。它主要生產的是國民經濟各部門&#xff08;包括采掘、化工、冶煉、能源、醫療衛生、環保等&#xff09;所急需的重大成套設備&#xff0c;例如礦產資源井采及露天開采設備、大型火電、水電、核電成套設備、石…

教育行業文本短信VS視頻短信VS語音短信哪個好?

在教育行業中&#xff0c;文本短信、視頻短信和語音短信各有其優勢&#xff0c;選擇哪種方式更好取決于具體的應用場景和目標。 文本短信的優勢在于&#xff1a; 1.簡潔明了&#xff1a;能夠快速、直接地傳遞信息&#xff0c;對于需要快速通知或提醒的場景非常適用。 …