在程式系統架構上有一個很重要的概念,我們會一層層的封裝,然後讓某一層的使用者不需要真的知道該層內部的如何運作,但只需要怎麼用即可,如此一來我們可以受益:
- 有效率的建立大型程式系統,不用全部混在一起
- 需要更改時,使用界面是相同的,修改內部程式,並不需要使用者也修改他的程式
拿影像處理的軟體舉例,一位藝術工作者只需要怎麼在上面按按鈕,不需要真的知道程式背後怎麼運作,而該軟體的工程師只要把使用界面保留相同樣子,內部功能怎麼優化、修改,並不會影響到使用者。把層級加大去思考,我們身邊很多的系統都是這樣疊加起來的。
所以,在寫C++程式碼的時候,把所有的code都放在同一個file並不是一個好主意,你可能到處修改,搞不定哪些已經完成,哪些還沒有,又說不定你想要跟別的程式共用這份code中的class,所以我們將自訂的class寫在不同的檔案,然後封裝,往後自己撰寫主程式(main)時候,不要去管class裡面怎麼運作,只要能拿來使用即可,如此才能有效率的完成較大的程式系統。
此外,我們把自訂class寫在header(.h檔)裡面,主程式只要呼叫該header就可以用自訂的class了(#include "student.h"),但是注意,這個header對於使用者(寫main,用include呼叫的人)來說,他不會想知道,也沒有必要讓他知道class內部怎麼寫,只需要讓他知道這class有什麼member data or function,所以我們只定義了名字在header:
student.h
#include <string> using namespace std; class Student{ public: Student(string name);// you can write "string" without name as argument, but it's more clear if you write it. string getName(); void setName(string name); private: string studentName; };
然後把class裡面的那些functions定義在同名的.cpp檔裡面,如下:
student.cpp
#include <iostream> #include "student.h" using namespace std; Student::Student(string name){ studentName = name; } string Student::getName(){ return studentName; } void Student::setName(string name){ studentName = name; }
注意這裡要:
- include student.h,程式才知道原本的class定義在哪裡
- 每一個function前面要加所屬的class::,不然compiler會當作這是普通的函式定義
我們稱這裡的header為interface,.cpp檔為implementation。
最後是使用者的程式:
main.cpp
#include <iostream> #include <string> #include "student.h" using namespace std; int main(){ string name; cout << "Insert Student Name >> "; cin >> name; Student a(name); cout << "His name is " << a.getName() << endl; a.setName("Heron Yang"); cout << "His name became " << a.getName() << endl; return 0; }
在compiler的時候需要把student.cpp和main.cpp的.o檔都產生之後,透過linker連結成一個執行檔,所以Makefile用下列的方法寫(Windows底下多半不用自己寫):
CC = g++#main : main.cpp student.cppall:g++ main.cpp -c -o main.og++ student.cpp -c -o student.og++ main.o student.o -o mainrm *.o
被註解的main : main.cpp student.cpp是比較簡易的方法,下方all:裡面只是比較清楚的實作過程。
No comments:
Post a Comment