C 11基礎語法知識總結(五)

2021-10-01 15:56:06 字數 3826 閱讀 9811

當過載的運算子為成員函式時,this指標繫結到左側運算物件上。成員運算子函式的顯式引數數量比運算物件少乙個。對於乙個過載的二元運算子來說,左側運算物件傳入第乙個引數,右側運算物件傳入第二個引數。如果作為成員運算子,則this指標所指內容預設作為左側運算子物件,函式只需傳入乙個引數,作為右側運算物件。

1、直接呼叫乙個過載的運算子函式

f1 +

= f2;

//類似內建版本的呼叫

f1.operator+=

(f2)

;//顯式類的成員函式呼叫

2、某些運算子不應該被過載

通常情況下,不應該過載逗號、取位址、邏輯與、邏輯或運算子。因為這些運算子的運算規則特殊,過載會導致和內建版本規則相異,使使用者無法適應。

3、使用與內建型別一致的含義

a、如果類執行io操作,則定義移位運算子使其與內建型別的io保持一致

b、如果類定義了operator==,那它也應該定義operator != 。

c、過載運算子的返回型別通常與內建版本的返回型別相容,邏輯運算子和關係運算子關係運算子應該返回bool,算術型別應該返回乙個類型別的值等。

4、過載運算子作為成員或者非成員

a、賦值、下標、呼叫和成員運算子都必須時成員

b、復合賦值運算子一般是成員

c、改變物件狀態的運算子或者與給定型別密切相關的運算子,如遞增、遞減和解引用運算子,通常是成員。

d、具有對稱性的運算子(兩邊的物件呼喚等價),如算術(+、-、*、/)、相等==等,通常是非成員函式。

1、過載operator<<,它的第乙個形參是乙個非常量的ostream物件的引用。因為向流寫入內容會改變其狀態,同時我們是無法直接複製乙個ostream的物件的。

2、輸出運算子盡可能減少格式化操作,這樣可以讓使用者有權控制輸出的細節

3、輸入輸出運算子必須是非成員函式,因外它的左側運算物件必須是iostream物件,而不能是某個其他的類物件。

4、輸入運算子必須處理輸入失敗出現的錯誤。

由於算術和關係運算子通常是可交換的(obj1+obj2與obj2+obj1是等價的),所以應該定義成類的非成員函式。

1、如果類同時定義了算術運算子和相關的復合賦值運算子,通常應該使用復合賦值運算子來實現算術運算子。

2、如果某個類在邏輯上有相等性的含義,則應該定義operator==

3、關係運算子定義規則:

a、定義順序關係,令其與關聯容器中對關鍵字的要求一致

b、如果類同時定義了operator==,則應該確定在定義時operator《的規則與其保持一致。

1、無論形參是什麼型別,賦值運算子都必須定義為成員函式

2、復合賦值運算子通常情況下應該定義為類的成員

1、下標運算子必須是成員函式

2、下標運算子通常定義兩個版本,乙個返回普通引用,乙個是類的常量成員函式並且返回常量引用。

定義遞增/遞減運算子的類應該同時定義前置版本和後置版本,同時,他們應該被定義為類的成員。

1、前置運算子返回遞增/遞減後的物件的引用

2、後置運算子定義時接受乙個額外的int型別的形參。當我們使用後置運算子時,編譯器為這個形參提供乙個值為0的實參。這個形參只是為了區分前置和後置版本。

3、後置運算子應該返回物件的原值,返回的是乙個值而非引用。顯式地呼叫後置運算子必須傳遞乙個整形值

1、在迭代器和智慧型指標類要定**引用運算子和箭頭運算子。

2、解引用運算子返回返回所指元素的乙個引用,箭頭運算子只是呼叫解引用運算子並返回解引用結果元素的位址。

3、箭頭運算子必須時類的成員,解引用運算子通常也是類的成員。

4、這兩個運算子通常定義為const的,因為獲取乙個元素不會改變物件本身的狀態,它獲取的時這個物件所繫結的非常量的元素。

5、對於箭頭運算子,如果是指向類物件的內建指標型別或者是乙個過載了operator—>的類的物件,等價的顯式呼叫形式分別為:

(*point).mem;

//point是乙個內建指標型別

point.

operator()

->mem;

//point是乙個類的物件

對於定義了operator—>的類的物件,是乙個遞迴呼叫過程,他不斷返回乙個過載了—>運算子的類物件,直到獲取乙個它所繫結的物件的內建型別指標,再按內建指標來呼叫—>運算子。

函式呼叫運算子必須是成員函式。乙個類可以定義多個不同版本的呼叫運算子,其引數數量或型別應該不同。

a、當定義乙個lambda時,編譯器會合成乙個未命名類的類物件,這個類中含有乙個函式呼叫運算子。

b、預設情況下lambda不能改變它捕獲的變數,因此lambda合成的類的中的函式呼叫運算子是乙個const成員函式。

c、lambda通過引用捕獲變數時,由程式保證執行時引用的物件確實存在,因此合成的類中不需要將其儲存為成員變數。

d、當採用值捕獲時,則會定義相應的資料成員,同時定義建構函式來初始化資料成員。

e、lambda表示式產生的類不含有預設建構函式、賦值運算子及預設析構函式;是否含有預設的拷貝/移動建構函式則視捕獲資料成員型別而定。

不同型別的可呼叫物件可能有相同的呼叫形式:

//函式

intadd

(int i,

int j)

//lambda表示式

auto mod =

(int i,

int j)

;//仿函式

struct divide

};

以上三種型別的可呼叫物件的呼叫形式都是int(int,int);但是這三種可呼叫物件的型別實際上是不同的,而且難以顯式表達。

假設一種場景:需要用容器儲存多個呼叫形式相同的不同型別的可呼叫物件,那麼容器的模板型別該設定成什麼呢?

a、通過使用function模板類就可以解決上述問題,function的模板引數就是可呼叫物件的呼叫形式,這樣就將呼叫形式相同的不同型別的可呼叫物件統一成一種型別了。

function<

int(

int,

int)

> f1 = add;

function<

int(

int,

int)

> f2 =

divide()

;function<

int(

int,

int)

> f3 = mod;

b、過載的函式與function

當乙個函式被過載了,我們就不能使用函式名來存入function中了:

int

add(

int i,

int j)

string add

(string i, string j)

如上例,如果存入add,會存在二義性,解決這個問題的方法就是存入函式指標,通過函式指標的返回值型別或引數型別來區分,或者函式物件及lambda來消除二義性(lambda其實隱含也是採用函式物件來區分的。)

int

(*fp)

(int

,int

)= add;

function<

int(

int,

int)

> f1 = fp;

C 11基礎語法知識總結 一

string類 1 issize decltype line.size m line.size vector類 1 早期的vector的元素還是vector,則需要在外層vector的右尖括號和其元素型別之間加乙個空格 vectorint 而新標準中可以直接採用 vectorint 2 最好在開始時...

C 11語法甜點

c 11中引入了許多簡化程式設計工作的語法上的新特性,我們暫且美其名曰 語法甜點 下面一一進行介紹。語法甜點1 序列for迴圈 序列for迴圈是一種簡化的for迴圈,可用於遍歷一組序列,包括各種容器 string 陣列 初始化列表以及由begin和end函式定義的序列。示例 如下 1 vectorv...

C 1 1知識準備

net的含義 一般指.net framework框架,是microsoft為開發應用程式而建立的乙個平台。net 的內容 主要包含乙個龐大的 庫。可以在客戶語言 如c 中通過物件導向程式設計技術 opp 來使用這些 這個庫分為多個不同的模組,這樣就可以根據希望得到的結果來選擇使用的部分。定義了基本的...