專(zhuān)業(yè)網(wǎng)站建設(shè)費(fèi)用怎么算怎么做一個(gè)自己的網(wǎng)站
名稱(chēng)空間只是用來(lái)對(duì)名稱(chēng)進(jìn)行管理的一種方式,首先要了解一下傳統(tǒng)C++名稱(chēng)空間。
1.聲明區(qū)域:聲明區(qū)域是指可以在其中聲明的區(qū)域,例如可以在函數(shù)外部聲明全局變量(區(qū)域?yàn)樗诘奈募?,在函數(shù)塊內(nèi)聲明局部變量(區(qū)域?yàn)樗诘膲K),其聲明區(qū)域就為其聲明位置。
2.潛在作用域:變量的潛在作用域從聲明開(kāi)始,到其聲明區(qū)域的結(jié)尾結(jié)束。但是潛在作用域比聲明區(qū)域小,因?yàn)樽兞勘仨毝x后才能使用。
然而,變量并不是在潛在作用域就是可見(jiàn)的,它可能被其他嵌套的聲明區(qū)域隱藏,例如:
int a = 0;
int main(){//同理int a = 1;{//在此聲明區(qū)域中,則會(huì)隱藏其他變量
int a = 2;}return 0;
}
在上面中,每個(gè)不同區(qū)域的同名變量會(huì)隱藏其他的同名變量,變量對(duì)于程序的可見(jiàn)性稱(chēng)為作用域。
而現(xiàn)在的名稱(chēng)空間則是C++為了解決名稱(chēng)沖突的問(wèn)題提供的空間工具。
C++關(guān)于全局變量和局部變量的規(guī)則定義了一種名稱(chēng)空間層次,每個(gè)聲明區(qū)域都可以聲明名稱(chēng),這些名稱(chēng)獨(dú)立于其他聲明區(qū)域中聲明的名稱(chēng)。在一個(gè)函數(shù)中聲明的局部變量不會(huì)和在另一個(gè)函數(shù)中聲明的局部變量沖突。
新的名稱(chēng)空間)
C++新增這樣一種功能,通過(guò)定義一種新的聲明區(qū)域來(lái)創(chuàng)建命名的名稱(chēng)空間,這樣做是為了提供一個(gè)聲明名稱(chēng)的區(qū)域。一個(gè)名稱(chēng)空間中的名稱(chēng)不會(huì)和另外一個(gè)空間中相同的名稱(chēng)沖突。
namespace Jill {double bucket(double n) {//statments}double fetch;struct Hill {int num;char gendet;};
}namespace Jack {double bucket(double n) {}double fetch;struct Hill{int a; double b;};}
默認(rèn)情況下,名稱(chēng)空間中聲明的名稱(chēng)的鏈接性是外部的(除非引用了常量).名稱(chēng)空間是開(kāi)放的,可以把名稱(chēng)添加到已有的名稱(chēng)空間中。
Jack::pail = 12.32;
Jill::pail = 23.32;
通過(guò)::(作用域解析運(yùn)算符)來(lái)使用該空間對(duì)應(yīng)的限定名。
未被修飾的名稱(chēng)成為未限定的名稱(chēng),包含名稱(chēng)空間的名稱(chēng)稱(chēng)為限定名稱(chēng)。
同時(shí)可以使用using 聲明和using 編譯指令來(lái)添加名稱(chēng)到聲明區(qū)域,例如:
//如果在外部使用,則將名稱(chēng)添加到全局聲明區(qū)域中
using namespace Jill;
int main() {//using聲明將特定的名稱(chēng)添加到它所屬的聲明區(qū)域中//通過(guò)聲明區(qū)域,將對(duì)應(yīng)名稱(chēng)添加到對(duì)應(yīng)名稱(chēng)空間中using Jill::bucket;//為Jill中的bucketbucket = 1;return 0;
}
當(dāng)只使用using聲明時(shí),using Jill::bucket只會(huì)將Jill空間中的bucket加載到對(duì)應(yīng)的main塊中的聲明區(qū)域中,而如果在全局聲明區(qū)域聲明則可以在整個(gè)文件中使用。
當(dāng)使用using 編譯命令時(shí),using namespace Jill會(huì)將其空間中所有變量添加到對(duì)應(yīng)聲明區(qū)域。
使用以上兩種方法都可以避免使用::作用域解析運(yùn)算符來(lái)聲明變量,而直接使用變量名即可,但是有一種情況下必須使用解析運(yùn)算符。
//正確,因?yàn)槎际遣煌臉?biāo)識(shí)符,內(nèi)存單元不同
jack::pal = 3;
jill::pal = 1;//錯(cuò)誤,會(huì)產(chǎn)生二義性,編譯器不知道使用哪個(gè)
using jack::pal;
using jill::pal;pal = 10; //which one?now have a conflict(用哪個(gè)?發(fā)生沖突)
同時(shí)還需要注意using聲明和using編譯的不同:
假設(shè)名稱(chēng)空間和聲明區(qū)域定義了相同的名稱(chēng),如果試圖使用using聲明將名稱(chēng)空間的名稱(chēng)導(dǎo)入該聲明區(qū)域,則這兩個(gè)名稱(chēng)會(huì)發(fā)生沖突,從而報(bào)錯(cuò).
int foom(){Hill top; //ERROR
Jill::Hill crest; //valid
}
如果使用using編譯指令將該名稱(chēng)空間的名稱(chēng)導(dǎo)入該聲明區(qū)域,則局部版本將隱藏名稱(chēng)空間版本.
int foom(){
using namespace Jill;Hill top;
Hill crest; //use local value}
一般來(lái)說(shuō)使用using聲明比using編譯指令安全,因?yàn)樗鼘?dǎo)入指定名稱(chēng),當(dāng)與局部名稱(chēng)發(fā)生沖突時(shí),編譯器將發(fā)出警告。,而使用using編譯命令如果發(fā)生沖突會(huì)默認(rèn)使用局部名稱(chēng)覆蓋命名空間名稱(chēng),不會(huì)發(fā)出警告。
名稱(chēng)空間支持者希望我們使用using聲明的方式去導(dǎo)入名稱(chēng),而不是使用using編譯的方式去導(dǎo)入。
但我們可使用嵌套式名稱(chēng)空間,創(chuàng)建一個(gè)包含常用using聲明的名稱(chēng)空間。
namspace elements
{
namespace fire
????????{
? ? ? ? int flame;
????????}
? float water;
}
在該嵌套空間中,flame指的是element::fire::flame。同樣,可以使用下面的using編譯指令使內(nèi)部名稱(chēng)可用
using namespace element::fire;
也可以在名稱(chēng)空間中使用using編譯指令和using聲明。
namespace myth
{
? ? ? ? using Jill::fetch;
? ? ? ? using namespace elements;
? ? ? ? using std::cout;
? ? ? ? using std::endl;
? ? ? ? using std::cin;
}
假設(shè)要訪問(wèn)Jill::fetch。由于Jill::fetch位于myth中,因此可以這樣訪問(wèn):
std::cin >> myth:fetch;
也可以使用Jill::fetch;來(lái)進(jìn)行訪問(wèn)。
?
接下來(lái)使用using編譯命令來(lái)用于myth名稱(chēng)空間情況。
using命令是可傳遞的,若A ->B,B->C,則A->C是可行傳遞的。
using namespace mythl; == (using namespace myth; using namespace elements;)
同時(shí)也可以給名稱(chēng)空間創(chuàng)建別名.?
namespace my_favorite_things{....};
則可用下面語(yǔ)句設(shè)置別名
namespace mvft?= my_favorite_things;
或者
namespace MEF = myth::elements::fire;
int main(){
? ? ? ? using MEF::flam;
? ? ? ? flam = 2;
}
未命名的名稱(chēng)空間
可以通過(guò)省略名稱(chēng)空間的名稱(chēng)來(lái)創(chuàng)建未命名的空間。
namespace{
? ? ? ? int ice;
? ? ? ? int bandycoot;
}?
?
名稱(chēng)空間示例
namesp.h文件
#ifndef NAME_SP_
#define NAME_SP_#include<string>namespace pers {//個(gè)人名稱(chēng)結(jié)構(gòu)struct Person{std::string fname;std::string lname;};//設(shè)置個(gè)人名稱(chēng)信息void getPerson(Person&);//查看名稱(chēng)信息void showPerson(const Person&);}namespace debts {//可傳遞using namespace pers;struct Debt{//名稱(chēng)結(jié)構(gòu)Person name;//金額double amount;};void getDebt(Debt&);void showDebt(const Debt&);double sumDebts(const Debt ar[], int n);}#endif // !NAME_SP_
namesp.cpp文件
#include<iostream>
#include"namesp.h"namespace pers {using std::cout;using std::cin;void getPerson(Person& rp) {cout << "Enter first name: ";cin >> rp.fname;cout << "Enter last name: ";cin >> rp.lname;}void showPerson(const Person& rp) {cout << rp.lname << "," << rp.fname;}
}//債務(wù)命名空間
namespace debts {//設(shè)置債務(wù)情況void getDebt(Debt& rd) {getPerson(rd.name);std::cout << "Enter debt: ";std::cin >> rd.amount;}//顯示名稱(chēng)和消費(fèi)金額void showDebt(const Debt& rd) {showPerson(rd.name);std::cout << ": $" << rd.amount << std::endl;}//計(jì)算金額總和double sumDebts(const Debt ar[], int n) {double total = 0;for (int i = 0; i < n; i++){total += ar[i].amount;}return total;}}
?main程序文件
#include<iostream>
#include"namesp.h"
void other(void);
void another(void);
int main() {using debts::Debt;using debts::showDebt;//創(chuàng)建一個(gè)債務(wù)結(jié)構(gòu)Debt golf = { {"Benny","Goatsniff"},125.2 };//查看對(duì)應(yīng)債務(wù)情況showDebt(golf);other();another();return 0;
}void other() {using std::cout;using std::endl;using namespace debts;//動(dòng)態(tài)創(chuàng)建一個(gè)Person結(jié)構(gòu)對(duì)象Person* dg = new Person{ "Doodles","Glister" };showPerson(*dg);delete dg;cout << endl;//創(chuàng)建一個(gè)Debt結(jié)構(gòu)的數(shù)組Debt zippy[3];int i;for (i = 0; i < 3; i++)getDebt(zippy[i]);for (i = 0; i < 3; i++)showDebt(zippy[i]);//顯示總計(jì)債務(wù)金額cout << "Total debt: $" << sumDebts(zippy, 3) << endl;return;
}void another() {using pers::Person;Person person = { "Milo","Rightshift" };pers::showPerson(person);std::cout << std::endl;
}
在頭文件namesp.h中,定義了兩個(gè)命名空間,其中pers中定義了一個(gè)結(jié)構(gòu)體Person用來(lái)存放用戶的名和姓。還提供了兩個(gè)函數(shù)原型,用于設(shè)置姓名和打印姓名。
另一邊使用namesp.cpp實(shí)現(xiàn)了命名空間中函數(shù)原型的定義,將原型的定義放入其中。
最后在main函數(shù)中通過(guò)頭文件引入對(duì)應(yīng)的命名空間,同時(shí)使用using聲明和using編譯命令將命名空間中的結(jié)構(gòu)體和函數(shù)引入,同時(shí)使用。
至此我們可以有一個(gè)初步對(duì)頭文件和命名空間的認(rèn)識(shí)了,我們將在頭文件中定義命名空間,聲明對(duì)應(yīng)空間中的變量信息,同時(shí)可以定義函數(shù)原型(類(lèi)似于接口),然后通過(guò)同名源文件去實(shí)現(xiàn)命名空間中的函數(shù)定義,或者定義外部變量,最后在main文件中引入頭文件,使用using聲明或者using namespace編譯命令來(lái)使用該命名空間中聲明的變量和函數(shù)。