初步理解 函式過載 和 運算子過載 轉

2022-02-14 12:03:10 字數 3582 閱讀 8139

比如我初學 c++ 時,早就知道指標實際就是某個變數的位址,就是不知道具體怎麼用。這感覺就彷彿學數學,我知道某定理,也知道某定理的證明是對的,但我就是不知道這東西有什麼用。直到學資料結構,接觸到鍊錶,才突然明白指標。

所以語法只是初步,更重要的是要想明白遇到什麼問題了,才需要有那個語法。之後再進一步,去**具體實現。

去想想過載函式過載,英文為 overloading,大概就是很多個的意思。

舉個例子,我需要個函式取 2 個 int 的最大值。函式介面應該是

(1) int max(int a, int b); 

那更進一步,我取3個 int 的最大值呢,介面可以定義為

(2) int max(int a, int b, int c);

函式 (1) 和 (2)的名字是一樣的,都叫 max,就只有引數的個數不同。這是函式過載。

那現在,我需要取兩個float的最大值呢,介面也可以定義為

(3) float max(float a, float b);

對比 函式(1) 和 (3),名字也是一樣的,引數個數也是一樣的。不過引數的型別不同。這也是函式過載。

所以函式過載就是,名字相同,但引數個數不同或者引數型別不同。

夠簡單吧。

不過,我相信到這裡還會似懂非懂的。那我們去設想一下,上面的例子,假如沒有過載,也就是函式的名字不可以相同,那會怎麼樣?

第(1)個函式,還是叫max吧。那第(2)個函式,就不能叫max了。就叫max3吧,因為有3個引數。這樣第(1)個函式還是叫max不好吧,就叫max2, 有兩個引數,跟max3對應起來。那第(3)個函式怎辦。因為是2個浮點。就叫max2f吧。f表示浮點。

那現在 max2, max3, max2f又不統一了。就叫 max2i, max3i, max2f, 吧。那到時 double, long, long long型別,各自有2個引數,或者3個引數。那就出現 max2i, max3i, max2f, max3f, max2l, max3l ......

同乙個取最大值的概念。出現了多個不同的名字。似乎不好吧。可能你覺得上面的例子是我作的,真實中應該不至於這樣吧。但實際上在 c 語言中,就發生這樣的事情。

c 語言就沒有函式過載的。下面都是 c 標準庫中取絕對值的函式。

float fabsf(float);

double fabs(double);

long double fabsl(long double);

int abs(int);

long labs(long);

long long llabs(long long);

有了過載和模板(模板這裡不說),c++ 中就為 std::abs,只有乙個名字。

另乙個例子,就是 c 語言寫的 opengl 介面,下面函式都是定義頂點。

glvertex4i

glvertex4s

glvertex2dv

glvertex2fv

glvertex2iv

glvertex2sv

glvertex3dv

glvertex3fv

glvertex3iv

glvertex3sv

glvertex4dv

glvertex4fv

glvertex4iv

glvertex4sv

無過載,同乙個概念,弄出這樣多名字了。

運算子過載運算子,就是 + - * / == != 那些符號。運算子過載,也就是可以重新定義那些運算子。

那有什麼用呢?舉個例子。

point 表示點。兩個點可以相加,相減,判斷是否等於....

假如沒有運算子過載。需要定義這樣的函式。

point point_add(const point& a, const point& b);

point point_sub(const point& a, const point& b);

使用起來,就是。

point c = point_add(a, b);

point d = point_sub(c, a);

又加又減,會變成

point d = point_add(a, point_sub(c, d));

而在 c++ 中重新定義運算符號,可以寫出這樣的**

point c = a + b;

point d = c - a;

....

point d = a + (c - d);

對比一下,運算子過載會更易讀易寫。

運算子過載可以算個語法糖,無這個東西還是可以寫**,不過沒有寫得那樣漂亮自然。當做一件事情很麻煩的時候,通常就偷懶不去做了。

再舉個我遇到的例子。最近用到個object-c 庫 masonry。object-c 沒有運算子過載,這個庫有些**寫起來是這樣寫的。不用管它的意思。就去感受一下。

make.top.equalto(superview.top).with.offset(padding.top);

make.left.equalto(superview.left).with.offset(padding.left);

make.bottom.equalto(superview.bottom).with.offset(-padding.bottom);

make.right.equalto(superview.right).with.offset(-padding.right);

.......

make.width.greaterthanorequalto(@200);

make.width.lessthanorequalto(@400);

同樣的含義,假如有了運算子過載。我相信可以寫成這樣。

make.top     == superview.top    + padding.top;

make.left == superview.left + padding.left;

make.bottom == superview.bottom - padding.bottom;

make.right == superview.right - padding.right;

......

make.width >= @200;

make.width <= @400;

看看**的美感。功能雖然一樣,但是否漂亮,會有根本的不同。

不過要注意。c++有些地方也會寫得很醜的,比較多餘的。同樣問題,不同的語言會有不同的做法。c++中的解決方法,不一定最好的。

C 運算子過載和函式過載

c 允許在同一作用域中的某個函式和運算子指定多個定義,分別稱為函式過載和運算子過載。過載宣告是指乙個與之前已經在該作用域內宣告過的函式或方法具有相同名稱的宣告,但是它們的引數列表和定義 實現 不相同。當呼叫乙個過載函式或過載運算子時,編譯器通過把您所使用的引數型別與定義中的引數型別進行比較,決定選用...

C 過載函式運算子和過載函式

c 允許在同一作用域中的某個函式和 運算子指定多個定義,分別稱為 函式過載 和運算子過載 過載宣告是指乙個與之前已經在該作用域內宣告過的函式或方法具有相同名稱的宣告,但是它們的引數列表和定義 實現 不相同。當您呼叫乙個 過載函式 或過載運算子 時,編譯器通過把您所使用的引數型別與定義中的引數型別進行...

運算子函式過載

1.運算子的本質是什麼?把運算子看作函式名,通過函式過載的方式為同乙個運算子實現不同規則的運算,故運算子過載的本質就是函式過載。2.怎樣進行運算子過載?運算子過載的函式名是由關鍵字operate和其後重要的運算子符號構成。運算子函式定義的一般格式如下 資料型別 operate 運算子符號 引數列表 ...