--- tags : Programming Language title: Programming Language(Chapter 1) --- <style> .title{ text-align:center; font-size: 26px; font-family: Arial; font-weight: bold; } .preview{ font-size: 20px; font-weight:bold; } .nav{ color:grey; font-size:10px; font-family:Arial; } .nav a{ font-weight:underline; } .reference{ color:darkred; font-weight:bold; font-size: 24px; } .reference .links{ color:grey; font-size: 16px; } .content{ color:black; font-size:20px; font-family:標楷體; } .content img{ display: block; margin-left: auto; margin-right: auto; } .content .ref{ font-size:16px; font-family:Times New Roman; } .content .ref a{ font-size:16px; color:gray; } .bot{ font-size:20px; font-family:標楷體; } .bot .left{ float:left; text-decoration:underline; } .bot .right{ float:right; text-decoration:underline; } .head{ font-size:13px; font-family:標楷體; } .head .left{ float:left; text-decoration:underline; } .head .right{ float:right; text-decoration:underline; } </style> {%hackmd lI2BjOvxRJCqsBR8dzVGQQ %} <span class="head"> <div class="left"> </div> <div class="right"> <a href="https://hackmd.io/@496NKil8SiiFZ4c2fHm3_g/r1RDKde4O" target="_self">下一章節</a> </div> </span><br> <div style="font-size:12px;font-family:標楷體;color:gray">建議會C語言(指標、struct與字元陣列等相關技術)再看此篇<br>若想要執行程式碼可以直接點圖片,進入Sololearn Code Playground執行</div> <span class=preview>Summary</span> [TOC] # <div class="title">Chapter 1: C++ 物件導向</div> <section class="content"> 對於C++,他保有所有C語言功能並且多了物件導向(object oriented)概念 <!--<img src="https://i.imgur.com/xAKB1az.png">--> </section> ## <div class="title">物件導向程式設計</div> <section class="content"> 物件導向式程式設計(Object Oriented Programming)提供了三個重要的程式技術: <ul> <li>封裝(Encapsulation)</li> <li>繼承(Inheritance)</li> <li>多型(Polymorphism)</li> </ul> </section> ### <div class="title">封裝?</div> <section class="content"> 簡單說就是將變數和函式打包起來。<br> 將變數和函式封裝在一起的集合體稱為類別(Class)。<br> 類別所宣告的變數則稱為物件(object)。<br> 以下為一個例子:<br><br> 今天有一個名為Dog的類別,其程式碼如下<br> <a href="https://code.sololearn.com/c54a83a9A220"><img src="https://i.imgur.com/lXktacV.png"></a> 這個Dog類別下有一個函式(Bark)和一個變數(name)。而puppy就是所謂的物件(object),也就是說他式Dog這個類別的變數。 </section> ### <div class="title">繼承?</div> <section class="content"> 封裝後的類別可以被繼承,變成新的類別。<br> 繼承者會接收來自被繼承類別中所包含的變數與行為(函式)。<br> 繼承者還可以依照本身的需求新增其他的變數與行為(函式)。<br> 以下為一個例子:<br><br> 今天有一個名為Animal的類別與兩個分別繼承Animal的子類別(Duck與Dog),其程式碼如下<br> <a href="https://code.sololearn.com/cA13A5A21a23"><img src="https://i.imgur.com/2TVfd0j.png"></a> 兩個子類別,Duck與Dog繼承了Animal這個類別,代表了Duck與Dog擁有Animal下的legs變數與walk行為(函式)。 </section> ### <div class="title">多型!</div> <section class="content"> 繼承式多型能實現的必要條件。<br> 所謂的多型也就是一個類別指標,能指向任意其子類別物件。<br> 以下為一個例子:<br><br> 今天有一個名為Animal的類別與兩個分別繼承Animal的子類別(Duck與Dog)。<br> 而今天只用一個Animal類別指標,指向Duck與Dog的物件,其程式碼如下: <a href="https://code.sololearn.com/ca2a20a5A2a0"><img src="https://i.imgur.com/PiCynu0.png"></a> Animal下有一個可以繼承的getLegs函式,而在其子類別(Dog與Duck)下,重新定義(override)了getLegs函式。<br> 我們就可以以更改Animal指標類別指向的物件,直接執行其對應的getLegs函式。 </section> ## <div class="title">C vs C++</div> <section class="content"> 上方提到 C++ 保有 C 的功能,也介紹了何謂物件導向(OOP)。<br> 而現在帶出C++與C多了那些功能。<br> <ul> <li>bool</li> <li>輸入輸出(cin、cout)</li> <li>多載函式</li> <li>多載運算子</li> <li>inline函式</li> <li>動態記憶體配置</li> <li>String類別</li> <li>樣板(template)</li> </ul> </section> ### <div class="title">輸入輸出(cin、cout)</div> <section class="content"> C++的cin與cout相較於C的scanf與printf。<br> 少了對應的變數型態,可以很方便的直接讀取值。<br> 需要注意的是因為cin與cout屬於iostream下的功能。定義在iostream下的名稱std名稱空間之中。<br>故通常都會在呼叫iostream函式庫後多加一行using namespace std<br> <div class="ref"> 參考資料:<a href="https://openhome.cc/Gossip/CppGossip/Namespace.html">簡介名稱空間</a> </div> </section> ### <div class="title">cin?? cin.getline!? getline????</div> <section class="content"> 知道C++下的cin相對於C的scanf後。接著介紹getline,我們可以將getline視為C語言中的gets,他能一次讀取一行輸入。(也就是說它可以讀取帶有空格的字串輸入)<br> 而getline下又分為istream下的函式(cin.getline())與string下的函式(getline())。 <ul> <li>istream流-cin.getline()</li> <li>string流 -getline()</li> </ul> <div class="ref"> 參考資料: <a href="https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/432734/">C :cin、cin.getline()、getline()的用法(Abstract)</a> </div> </section> #### <div class="title">cin.getline(字串,長度)</div> <section class="content"> 用法很明確,可以接收n個長度的字元陣列。相對的要注意的是跟之前gets與scanf一樣,當混合使用時需要多一行cin.get()來讀取一個'\n'字元。 </section> #### <div class="title">getline(來源,字串)</div> <section class="content"> cin.getline與 string下的getline最大差異在於,他可以選擇來源,可以做到字串分割(同原c的strtok)。<br> 而單純抓取輸入的話,則將來原設置成cin。<br> 即getline(cin,字串),而此getline則是讀到'\n'才結束,同樣也能達到達取帶空白的字串。 <a href="https://code.sololearn.com/c7a11a14A24a"><img src="https://i.imgur.com/4q3QCuY.png"></a> 上方例子為以getline讀取一行string(字串),將他交給stringstream進行處理,就能以stringstream下在getline裡進行字串分割。 </section> ### <div class="title">多載函式</div> <section class="content"> 科普一下<br> 一個函式的定義如下<br> 回傳值 函式名稱(型態 引數,型態2 引數2, ...){...}<br> int   calc   (int num) {...}<br><br> 所謂的多載函式,也就是同樣名稱的函式,可以有不同的輸入輸出方式。<br> 就以之前用過的math.h函式庫下的pow(n,m)為例,pow(n,m)函式為n的m次方。<br> 可是我們可能會有整數(int)的n與整數(int)的m,或浮點數(double)的n與浮點數(double)的m。若在原本 C 語言下不能一次定義兩個函式,但式C++新增了多載函式功能,達到能以不同輸入(double與int)但式執行相同效果的函示出現。<br><br> 簡單以一個例子舉例:<br><br> 今天想要做一個程式,他能執行一個算式a+b,但是不確定兩變數的型態,可能是int也可能是double。程式可以這樣寫 <a href="https://code.sololearn.com/ca21A5a17A22"><img src="https://i.imgur.com/nEhwzej.png"></a> <br><br> 多載函式不只能做到不同型態的(引數)輸入,也能做到同個函式名稱,多個變數(引數)輸入。<br>也就是說可以達到,只需要一個變數(引數),兩個變數(引數)甚至不用變數(引數)也能執行這個函式。<br><br> 以上方例子再去增加,假設今天不只兩數做加減。程式碼如下。 <a href="https://code.sololearn.com/ca9A197a21a1"><img src="https://i.imgur.com/FP2eR9t.png"></a> </section> #### <div class="title">多載函式(預設值)</div> <section class="content"> 在一種情況,類似要輸出文字,但是不知道文字大小,文字顏色等信息,我們這時候就可以利用預設值,來達到不用值也能正常使用函式。<br>原理跟多載函式差不多,可以將它看作多個相同名稱的函式,只是有預先定義某變數(引數)的值<br> 以剛剛敘述的例子為例,程式碼如下:<br> <a href="https://code.sololearn.com/c19A11A221a1"><img src="https://i.imgur.com/1fk4m9C.png"></a> <br> 在預先定義函式下設定預設值,以上方為例。 <a href="https://code.sololearn.com/cA72A19a15A8"><img src="https://i.imgur.com/TyDkNfM.png"></a> 下方就不用再次設定變數(引數)初始值。 </section> #### <div class="title">多載函式(*限制)</div> <section class="content"> 雖然多載函式有它的好處,能讓程式設計師不用再去想額外名字。<br> 但相對的一訂有他的缺點,在一般多載函式下有相同的函式名稱不能有相同的引數個數與型別,即使回傳值不一樣,編譯其無法判斷該使用哪個函式。ex:<br> <ul> <li>int add(int,int);</li> <li>long add(int,int);</li> </ul> 而在設定預設值時,預設值必須從最右側的引數往回,不能從左側引數。ex:<br> <ul> <li>void abc(float k, int j, int i=5) //對</li> <li>void xyz(float k=1,int j, int i) //錯</li> <li>void err_use(float k, int j=2, int i) //錯</li> </ul> </section> ### <div class="title">多載運算子</div> <section class="content"> 多載運算子在此先簡單帶過,能定義一個類別(classes)的運算(operate)方式,其所有運算子如下。 <img src="https://i.imgur.com/JJB6keH.png"> </section> ### <div class="title">inline 行內函式</div> <section class="content"> 將一個函式改成inline函式,只需要在前面加上inline關鍵字。<br> inline的功能類似巨集,編譯器會在乎較inline處,直接將程式碼嵌入到原始程式中。<br> 但是相對的,他只能將程式帶過去,所以類似static變數、迴圈、switch、遞迴等功能如果在inline函式裡,編譯器可能無法在呼叫點展開,則帶有inline關鍵字的函式將會忽視掉inline功能。 </section> ### <div class="title">動態記憶體配置</div> <section class="content"> 所謂的動態記憶體配置,也就是將變數固定位置,如果不去做刪除,他一直都在直到程式結束。<br> 會用到動態記憶體的時候大多數都是為了做到跳脫函式,也就是今天在此函式能讀取main裡的A變數,但是也想要在另一個函式讀取main裡的A變數。<br><br> 而C++的動態記憶體配置與C的用法差異不大,只差在定義與刪除,而且也適用之前的功能。 <table> <tr> <td>方式\語言</td><td>C</td><td>c++</td> </tr> <tr> <td>新增</td><td>規劃一個大小的記憶體位置<br>malloc(sizeof(資料型別))<br> </td><td>不需要指定大小,可直接配置<br>new 資料型別<br>new 資料型別[大小]</td> </tr> <tr> <td>刪除</td><td>free 指標變數<br> </td><td>delete 指標變數<br>delete [] 指標變數</td> </tr> </table> </section> ### <div class="title">iomanip函式庫 格式化輸出</div> <section class="content"> 在C++下有一個函式庫"iomanip",可以搭配cout做到格式化輸出。<br> 在此只簡單介紹幾個常用的,更多資訊可以查看下方的參考資料 <ul> <li>fixed 以正常的數字格式顯示</li> <li>setprecision(int n) 指定顯示精確度</li> </ul> <div class="ref"> 參考資料:<a href="https://openhome.cc/Gossip/CppGossip/IOFormatController.html">I/O 格式控制器</a> </div> </section> #### <div class="title">fixed</div> <section class="content"> 小數位數不足時補0 </section> #### <div class="title">setprecision(int n)</div> <section class="content"> 設定小數點位數為n位 </section> <span class="bot"> <div class="left"> </div> <div class="right"> <a href="https://hackmd.io/@496NKil8SiiFZ4c2fHm3_g/r1RDKde4O" target="_self">下一章節</a> </div> </span>