<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
C++語法設計很巧妙,比如運運算元過載一個 >
bool operator>(const Date& d) { return !(*this <= d); }
這裡可以結合前面的行內函式來進一步提高程式碼的效率,而行內函式不支援 .h 和 .cpp 分開寫,所以成員函數要成為行內函式最好的辦法就是把定義放在類裡面,類裡面定義的會被預設為是 inline 行內函式。
我們計算日期類的加法時:
Date Date::operator+(int d) { Date ret(*this); ret.day += d; while (ret.day > Getmonth(ret.year, ret.month)) { ret.day -= Getmonth(ret.year,ret.month); ret.month++; if (ret.month == 13) { ret.year += 1; ret.month = 1; } } return ret; }
我們可能會有這樣的問題,這裡面 += 和 + 兩個運運算元其實是一樣的,實現原理上沒什麼差別,那你可能會封裝個函數來解決他們的關係,但是其實直接讓他倆互相附庸,分為了 += 複用+ 和 + 複用 += 兩種辦法:
1.+= 複用 +:
2.+ 複用 +=(更優):
兩種乍一看其實沒什麼區別,但是其實有優越和劣勢可以分的,很 += 是不需要構造的,因為它是傳參照呼叫(返回值為域外的 this 指標的內容,必須要傳參照),但是 + 是必須要構造的,拷貝區域性物件的 ret 和 最後的 return , 一共需要構造兩次。
讓 += 複用 +,+在先就會讓整個過程構造 4 次,而讓 + 來複用 += 的話,+ 還是構造 2 次沒得說,但是 += 就不需要拷貝構造了,整個過程就只需要構造 2 次,消耗就會小很多。咱就應該多摳摳細節,寫出正確的程式碼固然重要,但是追求更優秀更高效的程式碼是每一個程式設計師的基本素養。
既然 +,- 能造,那 ++ 和 – 自然也不在話下,但是這就不好玩了啊, num++ 和 ++num 功能上都是 +1,寫成運運算元過載格式都是
Date Date::operator++();
我們該怎麼區分呢?要知道函數名相同而引數不同就應該敏感使用函數過載,C++這個大聰明是不會考慮不到這些的,因此就有了對應的語法:前置不帶引數而後置帶引數
Date operator++();//前置++
Date operator++(int d);//後置++
Date& operator++()//前置 { *this += 1; return *this; } Date operator++(int)//後置 { Date tmp(*this); *this += 1; return tem; }
其實括號裡面這個引數並沒有任何意義,單純只是用來區分前置與後置的寫法,所以這裡不寫形參也是可以的,我這裡就只給了一個型別。還有這裡千萬不要想著去加一個預設值,顯式傳參還好,要是不傳參編譯器就沒辦法區分開來,屬於是沒事找事了。
給一個場景:
void Func(const Date& d)
{
d1.Print();
}
void test()
{
Date d1(2022,5,19);
d1.Print();
Func(d1);
}
這個場景下就會報錯:
說實在的,這個報錯我自己也看的雲裡霧裡,為什麼 Print 那裡不報錯到了 Func 裡面 Print 就要報錯?Print 傳的過去 Func 就傳不過去了?究其為什麼會報錯,其實涉及到一個許可權問題。
void Print(Date* const this) { cout<<year<<"-"<<month<<"-"<<day<<endl; }
我們知道 Print() 的引數其實是 Date& const this ,在上面場景中去呼叫 Print 時其實引數是 &d1,傳物件的地址。在 Print 定義時 const 修飾的是 this 指標,const 修飾的變數可以初始化,此時指標不能被改變但是他指向的內容可以被初始化和修改;而 Func 的 const 修飾 Date*,他指向的內容不能被修改,所以這是一個經典的許可權放大問題。
const Date* 要傳給 Date* ,所以我們需要一個 const 進行修飾保護,但是 this 本質是一個隱含形參,我們沒辦法顯式呼叫,也就是說 const 沒辦法進行修飾。那麼C++也提供了一種修飾方法打破這個僵局,就是在函數尾巴加上 const。
void Print() const {}
尾巴上的 const 編譯器就會預設你是加在了函數原本定義的前面,這樣就完美了。
我們在程式碼中使用的 << , >> 為流輸入和流提取操作符,只要涉及輸入或者輸出資料,我們立馬想到的就是 cin 和 cout,這倆貨其實是全域性的物件, cin 對應 istream 類,cout 對應 ostream 類,它們都宣告在 標頭檔案中,這也解釋了“為什麼在 C++ 程式中引入 就可以使用 cin 和 cout”。
我們之所以可以在 <<, >> 之後接上任何型別,是因為強大的語法對每種型別進行了過載,能自動識別型別的本質就是函數過載,所以如果一個 int 型別的流插入 cin<<1 其實是 cin . operator <<(1)。
與其他函數不同,建構函式除了有名字,參數列和函數體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化欄位,初始化列表可以看成是物件的成員變數定義的地方:
class Func { public: Func(int a): _a(a){} // 初始化列表 private: int _a; };
注意:每個成員變數在初始化列表中只能出現一次因為初始化只能初始化一次,還要明確哪些成員必須放在初始化列表進行初始化:
其他變數即可以在初始化列表初始化也可以在函數體內初始化,內建型別成員不處理時,會呼叫預設建構函式即隨機值,如果我給出預設值,那麼之這個值就是給初始化列表用的,如果在初始化列表也同時給出這個內建型別的初始化值,就會採用初始化列表的值。我們應該儘量在初始化列表就初始化完,這樣能儘可能的減少很多毛病效率也高。
再來看看這個題目:
這個程式的結果是啥?
答案是 1 和隨機值,因為成員變數在類中的宣告次序就是他在初始化列表中的初始化順序,與他在初始化列表中的先後次序無關。_a2 先宣告 _a2 = _a1,此時 _a1 為隨機值,所以 _a2 為隨機值,_a1 為 1。
建構函式不僅可以構造和初始化物件,對於單個引數的建構函式,還具有型別轉換的作用。在C語言裡面我們就知道有隱式型別轉換,其實在 C++ 裡面也是一樣的,比如針對我定義的一個 Date(int year):
Date d1(2022); Date d2 = 2022;
顯然, 這裡 d2 需要的是 Date 型別的引數, 而我們傳入的是一個int, 這個程式卻能成功執行, 就是因為這隱式呼叫,另外說一句, 在物件剛剛定義時, 即使使用的是賦值操作符 = , 也是會呼叫建構函式, 而不是過載的 operator= 運運算元。這兩個語句對應前者是構造,而後者是構造+拷貝構造,相當於發生了隱式型別轉換, 如果我們寫成:
explicit Date(int year)
這個關鍵字會阻止這種轉換的發生。
到此這篇關於C++全面精通類與物件的文章就介紹到這了,更多相關C++類別與物件內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45