??
???????????????????????????????????????????博主主頁:Yan. yan.
??????????????????? ??????????????????????????C語言專欄
????????????????????????????????????????????數據結構專欄
?????????????????????????????????????????力扣牛客經典題目專欄
?????????????????????????????????????????????????????C++專欄
1、 運算符重載
??C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數名的函數,也具有其返回值類型,函數名字以及參數列表,其返回值類型與參數列表與普通的函數類似。
??函數名字為:關鍵字operator后面接需要重載的運算符符號。
??函數原型:返回值類型 operator操作符(參數列表)
以等號為例:
返回類型 operator=(類型 參數1, 類型 參數2)
{
}
注意:
- 不能通過連接其他符號來創建新的操作符:比如operator@
- 重載操作符必須有一個類類型參數
- 用于內置類型的運算符,其含義不能改變,例如:內置的整型+,不 能改變其含義
- 作為類成員函數重載時,其形參看起來比操作數數目少1,因為成員函數的第一個參數為隱
藏的this - " .* ", " :: ", " sizeof ", " ?: ", " . " 注意以上5個運算符不能重載。這個經常在筆試選擇題中出現。.
2、重載運算符的使用
??在全局使用重載運算符時,以==為例:
bool operator==(Data& a1, Data& a2)
{return a1._year == a2._year && a1._month == a2._month && a1._day == a2._day;
}
??但是在使用的時候卻發生了報錯,這是因為類中的成員變量是私有的,被保護起來了,不可以直接去訪問,所以,我們可以將重載函數放入類域中,將其變成類的成員函數
運算符重載函數的調用:
int main()
{Data a1(2024, 7, 10);Data a2(2024, 7, 11);cout << (a1 == a2) << endl;a1.Print();a2.Print();return 0;
}
3、賦值重載運算符
賦值運算符重載格式
- 參數類型:const T&,傳遞引用可以提高傳參效率
- 返回值類型:T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續賦值
- 檢測是否自己給自己賦值
- 返回*this :要復合連續賦值的含義
Data& operator=(const Data& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
??其中有關參數類型有兩種不同寫法,一種是寫為Date,另一種是寫為Date&,其主要使用場景為:
- 若在函數調用生命周期結束時,返回的對象沒有被銷毀,則使用引用返回 “ Date& ”。
- 若在函數調用生命周期結束時,返回的對象被銷毀了(即局部變量),則使用傳值返回。
傳值返回
??在C++中,當函數調用結束時,如果返回的是局部變量,那么所返回的值并不直接是局部變量的值,而是局部變量的臨時拷貝,當函數調用結束時,局部變量被銷毀,而臨時變量并沒有被銷毀,而作為返回值傳遞給了接受值,例如:
Data Func()
{Data a1(2024, 7, 10);return a1;
}int main()
{Data a2(Func());a2.Print();return 0;
}
??如果函數調用中所返回的變量是局部變量,如果使用引用的方式來接收會怎么樣呢?
??此時出現了錯誤,這是因為臨時變量作為編譯器所創建的變量,不可以被修改,正確的寫法如下:
引用返回
??引用返回時,是將函數內的變量的別名返回,并使用引用的方式接收。
Data& Func(Data& a)
{Data& a2 = a;return a2;
}int main()
{Data a1(2024, 7, 10);Data& a2 = Func(a1);a2.Print();return 0;
}
賦值運算符只能重載成類的成員函數不能重載成全局函數
??原因:賦值運算符如果不顯式實現,編譯器會生成一個默認的。此時用戶再在類外自己實現一個全局的賦值運算符重載,就和編譯器在類中生成的默認賦值運算符重載沖突了,故賦值運算符重載只能是類的成員函數。
用戶沒有顯式實現時,編譯器會生成一個默認賦值運算符重載,以值的方式逐字節拷貝。
??注意:內置類型成員變量是直接賦值的,而自定義類型成員變量需要調用對應類的賦值運算符重載完成賦值。
class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year = 1970;int _month = 1;int _day = 1;// 自定義類型Time _t;
};int main()
{Date d1;Date d2;d1 = d2;return 0;
}