學(xué)習(xí)c++的同學(xué)大概非常習(xí)慣在程序的開頭部分加上這句:
using namespace std;
可能由于太熟悉了络断,反而忽略了這句到底是做什么的劣像。這句中,一共有3個關(guān)鍵字橄仆,拋開第三個關(guān)鍵字std剩膘,我們只關(guān)注于前面的2個:using和namespace。
先說using盆顾,using一般來說有2個功能:
1 將std命名空間的內(nèi)容引入本命名空間怠褐,這句話很抽象,但是簡單說您宪,就是可以讓你少打幾個字奈懒。原來需要std::string這樣才能訪問的地方,可以簡化為string就可以了宪巨。當(dāng)你的命名空間很長很復(fù)雜時磷杏,using顯的很有用,比如:
namespace abcd
{
namespace efgh
{
namespace ijk
{
class A;
}
}
}
如果你想訪問A捏卓,那么完整的寫法是:abcd::efgh::ijk::A极祸。
當(dāng)然了,不得不承認(rèn)怠晴,using的存在是和namespace的封裝思想相違背的遥金,所以在通常的編程規(guī)范里,嚴(yán)禁在頭文件中using命名空間蒜田。
2 使用父類被隱藏的函數(shù)稿械。比如:
class A
{
public:
int fun(int);
void fun();
};
class B : public A
{
public:
using A::fun;
int fun(double);
};
B b;
b.fun();//without using, error
這里面涉及c++繼承的隱藏,不展開物邑。
其實(shí)using的作用非常有限溜哮,而且通常情況下屬于那種可有可無的.....
而另一個關(guān)鍵字namespace,就相對來說重要的多色解,namespace的存在茂嗓,使得一些大型的項目開發(fā)變得相對容易,各個模塊可以非常完美的區(qū)分開來科阎,再也不用擔(dān)心和其他人的函數(shù)或者類重名述吸。
namespace的實(shí)現(xiàn)原理非常簡單,在編譯時,同一個命名空間的函數(shù)或者變量將在名字前增加命名空間名蝌矛,比如上文中我們的class A道批,在編譯后可能變成: abcd_efgh_ijk_A。
在自己的命名空間內(nèi)有個函數(shù)入撒,它正好和全局范圍內(nèi)的某個函數(shù)重名隆豹,比如:
int fun(); //global
namespace A
{
int fun()
{
::fun(); //call golbal fun
}
}
前面的這些基本上都是鋪墊......
接下來才是重點(diǎn)....
我們在編寫一個類的時候,經(jīng)常會在這個類中用到其他類的一些信息茅逮,比如:
// a.h
namespace lbs
{
class A
{
int a;
...
};
}
// b.h
namespace lbs
{
class B
{
A a;
...
}
}
在上文中璃赡,如果想在類B中組合類A,那么需要在b.h中#include "a.h"献雅,因為編譯器需要A的定義碉考,而需要A定義的目的是為了確定A的大小以便在編譯時分配空間。
如果在b.h中#include "a.h"挺身,那么程序的耦合度會很高侯谁,因為你將在a.h中將許多不必要的信息都添加進(jìn)來,尤其是當(dāng)B這個類很大時章钾,你需要在b.h中#include非常多的類墙贱,程序?qū)@得異常笨重,而且邏輯很混亂伍玖。
有沒有解決方案呢嫩痰?
順著我們剛才的思路,編譯器需要的是A的大小窍箍,那么只需要將A a串纺,變?yōu)锳* a或者A& a,就可以了椰棘。在b.h中纺棺,不再#include "a.h",而是使用一個類的聲明替代邪狞,如下:
// b.h
namespace lbs
{
class A; //declare
class B
{
A* a;
...
};
}
這樣之后祷蝌,可以使得b.h輕便許多,程序整體的耦合度很低帆卓,可是當(dāng)你需要使用一個其他命名空間的類巨朦,該如何做呢?比如下面這樣:
// a.h
namespace lbs
{
namespace common
{
class A
{
int a;
...
};
}
}
// b.h
namespace lbs
{
namespace db_mm
{
class common::A;//error, common unknown
class B
{
A* a;
...
};
}
}
這種涉及不同命名空間的聲明剑令,如果按照上面的方式寫糊啡,將會編譯錯誤,提示common命名空間unknown吁津,因為系統(tǒng)不知道common是一個命名空間棚蓄。所以呢,需要這樣寫:
// b.h
namespace lbs
{
namespace common
{
class A; //declare
}
namespace db_mm
{
class B //definition
{
common::A* a;
...
};
}
}
當(dāng)然了,在cpp文件中梭依,還是需要#include所需要的所有頭文件稍算。