如何降低編譯的依存關係
tags: C++ Concept2
依存關係
依存關係指的是A class的實作必須在寫在B class之前,他們之間存在相依關係,A一定要寫在B之前;或A檔案一定要先被編譯,他們之間不能夠單純依靠宣告來通過編譯。
以下降低解說難易度將檔案縮減至一個單一檔案敘述
假如有一個自訂類別為 Name
// Name class 前置性宣告
class Name;
// Name class 定義 (不是成員函式定義)
class Name{
public:
Name(string n);
friend ostream& operator<<(ostream& out, Name const & n);
private:
string n;
};
那麼要使用這個型別的時候,該class定義必須出現在使用之前
// Name class 宣告
// Name class 定義
Name a("chg");
如果你把class定義移動到下方則會出問題
(Name的函式定義可以移動到下方)
(Name的函式定義可以移動到下方)
// Name class 宣告
Name a("chg");
// Name class 定義
則會出現相依的問題,產生Name的時候找不到定義;其他class如果要使用Name這個class,會造成Name一定要擺在那之上才可以編譯,如果要交錯互相使用麻煩就大了,誰在上都不對。
Handle Class
解決辦法,可以使用指針來占個位置不把它實作,這樣就不會需要他的實作了
只需要前置性宣告。
// Name class 宣告
Name* a;
// Name class 定義
應用在剛剛說的問題上代碼大概就長這個樣子
// Tw class定義
class Name;
class Tw{
public:
Tw(string name);
private:
Name* n;
};
// Name class定義
class Name{
public:
Name(string n);
friend ostream& operator<<(ostream& out, Name const & n);
private:
string n;
};
// Tw建構子
Tw::Tw(string name): n(new Name(name)){
cout << "n=" << *n << endl;
}
// Name 函式定義
Name::Name(string n): n(n){}
ostream& operator<<(ostream& out, Name const & n){
out << n.n;
return out;
}
如此一來順序的相依性就變得兩者皆可(函式的定義也是)
此外這裡的指針也可以使用沒有初始化的vector取代
此外這裡的指針也可以使用沒有初始化的vector取代
vector<Name> n;
不要初始化內容
vector<Name> n("name");
也不要初始化長度
vector<Name> n(1);
反例中的代碼因為Name沒有預設建構子(引數可為無的建構子),僅能使用 push_back() 初始化
// Tw建構子
Tw::Tw(string name){
n.push_back(name);
cout << "n=" << n[0] << endl;
}
Protocol Class
利用虛擬函式的特性,不需要先做,藉此避開宣告時必須要要定義的狀況。
// Name class 宣告
// 純虛擬類別定義(抽象類別宣告內含Name)
// Name class 定義
// 繼承抽象類別
參考代碼
Handle Class
/*****************************************************************
Name : Handle Class
Date : 2017/05/04
By : CharlotteHonG
Final: 2017/05/04
*****************************************************************/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Tw class定義
class Name;
class Tw{
public:
Tw(string name);
private:
Name* n;
// vector<Name> n;
};
//================================================================
int main(int argc, char const *argv[]){
Tw a("chg");
return 0;
}
//================================================================
// Name class定義
class Name{
public:
Name(string n);
friend ostream& operator<<(ostream& out, Name const & n);
private:
string n;
};
// Tw建構子
Tw::Tw(string name){
n = new Name(name); // point
// n.push_back(name); // vector
cout << "n=" << n[0] << endl;
}
// Name 函式定義
Name::Name(string n): n(n){}
ostream& operator<<(ostream& out, Name const & n){
out << n.n;
return out;
}
Protocol Class
/*****************************************************************
Name :
Date : 2017/05/04
By : CharlotteHonG
Final: 2017/05/05
*****************************************************************/
#include <iostream>
using namespace std;
// Tw class定義
class Name;
class Tw{
public:
virtual ~Tw(){}
virtual string name()=0;
static Tw* makeTw(Name const & name);
};
// Name class定義
class Name{
public:
Name(string const & n);
operator string&(){
return n;
}
friend ostream& operator<<(ostream& out, Name const & n);
private:
string n;
};
//================================================================
int main(int argc, char const *argv[]){
Tw* p;
Name chg = string("chg");
p = Tw::makeTw(chg);
cout << p->name() << endl;
return 0;
}
//================================================================
// Tw class定義
class RealTw: public Tw{
public:
RealTw(Name const & name): n(name){}
string name(){return n;}
private:
Name n;
};
// makeTw 函式定義
Tw* Tw::makeTw(Name const & name){
return new RealTw(name);
}
// Name 函式定義
Name::Name(string const & n): n(n){}
ostream& operator<<(ostream& out, Name const & n){
out << n.n;
return out;
}
沒有留言:
張貼留言