[c++] Operator overloading

Introduction


函數重載

關於重載 Overloading,最基本的是根據如下兩個特性:html

    • 基於參數
    • 基於const

其實,函數重載也沒啥多餘值得說的東西。ios

  

自定義操做規則

c++的操蛋屬性:本身爲一檔,空一檔,其餘隨意。c++

UB_stack a; UB_stack b = a; // copy
auto c = a; auto d {a};   // (or auto d = {a}), deduced type is std::initializer_list

這是一個抓狂的問題,詳見:http://scottmeyers.blogspot.com.au/2014/03/if-braced-initializers-have-no-type-why.html
函數

 

大神的無奈

今日一樂:爲什麼感受到了Scott對chinese edition是黑白版本的好奇和無奈。this

 

可重載運算符/不可重載運算符

Goto: C++ 重載運算符和重載函數spa

下面是:可重載的運算符列表.net

雙目算術運算符 + (加),-(減),*(乘),/(除),% (取模)
關係運算符 ==(等於),!= (不等於),< (小於),> (大於>,<=(小於等於),>=(大於等於)
邏輯運算符 ||(邏輯或),&&(邏輯與),!(邏輯非)
單目運算符 + (正),-(負),*(指針),&(取地址)
自增自減運算符 ++(自增),--(自減)
位運算符 | (按位或),& (按位與),~(按位取反),^(按位異或),,<< (左移),>>(右移)
賦值運算符 =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空間申請與釋放 new, delete, new[ ] , delete[]
其餘運算符 ()(函數調用),->(成員訪問),,(逗號),[](下標)

 

下面是:不可重載的運算符列表指針

成員訪問運算符 .
成員指針訪問運算符 .*, ->*
域運算符 ::
長度運算符 sizeof
條件運算符 ?
預處理符號 #

 

運算符重載實例

序號 運算符和實例
1 一元運算符重載
2 二元運算符重載
3 關係運算符重載
4 輸入/輸出運算符重載
5 ++ 和 -- 運算符重載
6 賦值運算符重載
7 函數調用運算符 () 重載
8 下標運算符 [] 重載
9 類成員訪問運算符 -> 重載

 

 

 

Overloaded Operator 


使用說明 - 簡單例子

重載符號:  ==code

 

聲明關鍵字operator,以及緊跟其後的一個c++預約義的操做符。舉例以下:htm

// 申明關鍵字
class
person{ private: int age; public: person(int a){ this->age=a; }
inline
bool operator == (const person &ps) const; };

// 實現方式以下 inline
bool person::operator == (const person &ps) const { if (this->age==ps.age)  // 這裏的this看上去是「符號」左邊的類 return true; return false; }

// 調用方式以下 #include
using namespace std; int main() { person p1(10); person p2(20); if(p1==p2) cout<<」the age is equal!」< return 0; }

 

 

使用說明 - 複雜例子

重載符號:  >>,  <<,  +,  +=

 

包括:(1) 輸入輸出;(2) 自增自減;(3) 運算

#include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <UB_stack.h>

using namespace std; class Test { public: Test(int x, int y):a{x},b{y}{} // The output operator must be defined as a friend function // and is usually a non-member function. // The input operator is similar.
    friend ostream& operator << (ostream&, const Test &); friend istream& operator >> (istream&, Test&); friend Test operator +(const Test&, const Test&);// Usually implemented as a member function.
    Test& operator += (const Test &); int returnA(void); void init(void); private: int a; int b; }; /******************************************************************************/

void Test::init(void) { this->a = 1; this->b = 1; } int Test::returnA(void) { return (this->a); } ostream& operator << (ostream &os, const Test &t) { os << t.a << " " << t.b << endl; } istream& operator >> (istream &is, Test &t) { is >> t.a >> t.b; } Test& Test::operator += (const Test &t) { this->a += t.a; this->b += t.b; return *this; } Test operator +(const Test &t1, const Test &t2) { Test ret = t1; ret += t2; return ret; } /******************************************************************************/

class SmallInt { public: friend ostream& operator << (ostream &os, const SmallInt &s); friend bool operator < (const SmallInt&, const SmallInt&); SmallInt(int v): value_{v} {} private: int value_; }; bool operator < (const SmallInt &rhs,const SmallInt &lhs) { return rhs.value_ <= lhs.value_; } std::ostream& operator<<(std::ostream &os, const SmallInt &s) { os << s.value_; return os; } /******************************************************************************/

int main() { cout << "Hello World!" << endl; Test t1{1, 2}; Test t2{10, 20}; /* * I/O Operators */ cout << t1 << t2; cin >> t2; cout << t1 << t2; t1.init(); t2.init(); /* * Compound Assignment Operators */ t2 += t1; cout << t2; /* * Arithmetic Operators */ cout << t1+t2; /* * Relational Operators * ... */
    
    
    /* * Using the STL Sort and Copy Algorithms */ vector<SmallInt> vec{SmallInt{3}, SmallInt{1}, SmallInt{2}}; sort(vec.begin(), vec.end()); copy(vec.begin(), vec.end(), std::ostream_iterator<SmallInt>(std::cout, " ")); return 0; }

 

 

操做符重載 與 友元函數

Ref: 有的操做符重載函數只能是友元函數

根本緣由:this 必須是第一個參數,且 this 默認是 private 的。

 

 

 

Advanced Usage


The Assignment Operator =

重載符號:  =

 

返回void,只是」賦值「的簡單版本:https://www.runoob.com/cplusplus/assignment-operators-overloading.html 

 

 

The Subscript Operator []

重載符號:  [ ]

 

  

* 定義實例:

class SafeArray { public: SafeArray(int s); SafeArray(const int v[], int s); ~SafeArray() {delete[] values;} int& operator [] (int i); int operator [] (int i) const; private: int size; int *values; }; SafeArray::SafeArray(int s) : size{s}, values{new int[size]} {} SafeArray::SafeArray(const int v[], int s) : size{s} { values = new int[size]; for (int i = 0; i < size; i++) { values[i] = v[i]; } } int& SafeArray::operator [](int index) { assert((index >= 0) && (index < size)); return values[index]; } int SafeArray::operator [](int index) const {  // 常函數不能修改 函數內的成員 assert((index >= 0) && (index < size)); return values[index]; }

 

* 使用樣例:

    SafeArray s{10}; // s[12] = 2; //這算是兩個operator,比較難,怎麼搞?
    cout << s[2] << endl;

 

 

Increment and Decrement Operators

 

重載符號:  ++, --

 

 

後綴法加了一個參數,有點意思。

From: https://www.runoob.com/cplusplus/increment-decrement-operators-overloading.html

#include <iostream>
using namespace std;
 
class Time
{
   private:
      int hours;             // 0 到 23
      int minutes;           // 0 到 59
public: // 所需的構造函數 Time(){ hours = 0; minutes = 0; } Time(int h, int m){ hours = h; minutes = m; }
// 顯示時間的方法 void displayTime() { cout << "H: " << hours << " M:" << minutes <<endl; }
// 重載前綴遞增運算符( ++ ) Time operator++ () { ++minutes; // 對象加 1 if(minutes >= 60) { ++hours; minutes -= 60; } return Time(hours, minutes); }
// 重載後綴遞增運算符( ++ ) Time operator++( int ) { // 保存原始值 Time T(hours, minutes); // 對象加 1 ++minutes; if(minutes >= 60) { ++hours; minutes -= 60; } // 返回舊的原始值 return T; } };

-------------------------------------------------------------
int main() { Time T1(11, 59), T2(10,40); ++T1; // T1 加 1 T1.displayTime(); // 顯示 T1 ++T1; // T1 再加 1 T1.displayTime(); // 顯示 T1 T2++; // T2 加 1 T2.displayTime(); // 顯示 T2 T2++; // T2 再加 1 T2.displayTime(); // 顯示 T2 return 0; }

 

 

 

The Arrow and Dereferencing Operators

重載符號:  -->, *

 

Ref: C++ 類成員訪問運算符 -> 重載

 

-> must be a member function and * is usually a member.

(Here 簡介)

貌似不錯的智能指針的博文:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html

The Basic Idea Behind All Smart Pointers

 

 

Type Conversion Operators

Conversion operators must be defined as member functions. They
do not take any parameters, nor do they specify a return type.
Typically conversions don’t modify the object and are declared
const.

 

若是去掉explicit,則User code中的line 2便可成立。

explicit: 聲明爲explicit的構造函數不能在隱式轉換中使用。

 

C++ 關係運算符重載

相關文章
相關標籤/搜索