Wednesday, January 18, 2012

Write C++ Code in Mutli-files

接續Class (C++)

在程式系統架構上有一個很重要的概念,我們會一層層的封裝,然後讓某一層的使用者不需要真的知道該層內部的如何運作,但只需要怎麼用即可,如此一來我們可以受益:

  • 有效率的建立大型程式系統,不用全部混在一起
  • 需要更改時,使用界面是相同的,修改內部程式,並不需要使用者也修改他的程式
拿影像處理的軟體舉例,一位藝術工作者只需要怎麼在上面按按鈕,不需要真的知道程式背後怎麼運作,而該軟體的工程師只要把使用界面保留相同樣子,內部功能怎麼優化、修改,並不會影響到使用者。把層級加大去思考,我們身邊很多的系統都是這樣疊加起來的。

所以,在寫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.cpp
all:
g++ main.cpp -c -o main.o
g++ student.cpp -c -o student.o
g++ main.o student.o -o main
rm *.o

被註解的main : main.cpp student.cpp是比較簡易的方法,下方all:裡面只是比較清楚的實作過程。