17.5.1 派生類
17.5.3 清除全域性的static
17.6 與c語言的相容性
18 cpp
1.「對所有不適合放進某個函式、某個struct或者某個編譯單元的名稱,c語言提供了乙個統一的全域性性的命名空間,這就帶來了名稱的衝突問題…在我設計型別安全的連線機制時…我注意到,對以下形式:
extern
"c"
的語法、語義和實現技術稍微做些修改,就能允許我們用以下形式:
extern ***
表示在***中宣告的名稱位於乙個分離的作用域***中,要從其他作用域中訪問就需要用限定的***::形式,和在類之外訪問靜態類成員完全一樣。
」 (p.351)
1.「…訪問命名空間成員採用訪問類成員的傳統記法:namespace_name::member_name。事實上,類作用域可以看成是命名空間作用域的一種特殊情況。」(p.355)
2.「考慮:
namespace a
;}
在命名空間括號中宣告的名稱就是在命名空間a內部的內容,它們不會與全域性的名稱或者其他任何命名空間中的名稱衝突。命名空間宣告(包括定義)與全域性宣告具有完全相同的語義,只是它們名稱的作用域被限制在命名空間內部。
程式設計師可以通過顯示限定的形式直接使用這些名稱:
a::string s1=
"annemarie"
;voidg1(
)
換一種方式,我們也可以顯示地讓某個特定庫中的個別名稱不需要限定描述而直接使用,這通過使用宣告完成。
using a::string;
string s2=
"nicholas"
;//meaning a::string
voidg2(
)
上述使用宣告在乙個區域性作用域為它所提出的名稱引進了乙個同義詞。
再換一種方式,我們也可以顯式地要求乙個特定庫中所有的名稱都直接被使用,不需要借助限定,這通過使用指示完成。
using
namespace a;
//make all names from a accessible
string s3=
"marian"
;//meaning a::string
voidg3(
)
上述使用指示並不為區域性作用域引進任何新名稱,而只是簡單地使有關命名空間中的所有名稱都變成可以訪問的。」(p.356)
1.「可以通過為長的命名空間提供短的別名的方式來解決:
//use namespace alias to shorten names;
namespace att = american_telephone_and_telegraph;
att::string s3=
"asdf"
;att::string s4=
"lkjh"
;
事實上,命名空間也能用於從多個命名空間組合出包含某些名稱的介面。
namespace my_inte***ce
」(p.359~360)
1.「使用宣告向區域性作用域中新增一些內容。使用指示則不新增任何內容,只是使一些名稱能夠被訪問,例如:
namespace x
int k;
voidf1(
)voidf2(
)
這樣也就維持了一種非常重要的性質: 區域性宣告的名稱(無論是通過正常的區域性宣告所宣告的,還是通過使用宣告)都將遮蔽名稱相同的非區域性宣告,而名稱的任何非法過載都將在宣告點被檢查出來。
如上所示,在全域性作用域中,在可訪問方面並不給全域性作用域任何超越命名空間的優先權,這也就為防止偶然的名稱衝突提供了某種保護。
在另一方面,非區域性的名稱在它們的宣告所在的上下文中查詢和處理,就像其他非區域性名稱一樣,特別是使用指示有關的錯誤都只在使用點檢查…例如:
namespace a
namespace b
voidf(
)
」(p.362~363)
1.「::f的意思是『在全域性作用域中宣告的那個f』,而x::f意味著『在命名空間x中宣告的那個f』。考慮:
int a;
voidf(
)
如果我們將它包裹到乙個命名空間中,再加上另乙個名稱為a的變數,得到的是:
namespace x
}
也就是說,用::限定意味著是『全域性』,而不是『外面包裹的最近命名空間』。
請注意,使用指示並不在它所出現的作用域中宣告任何名稱:
namespace x
using
namespace x;
//make all names from x accessible
using x::b;
//declare local synonym for x::b
int i1=
::a;
//error: no 'a' declared in global scope
int i2=
::b;
//ok: find the local synonym for x::b
」(p.363)
1.「…依據常規的過載規則,允許跨命名空間的過載。考慮:
namespace a
using
namespace a;
namespace b
using
namespace b;
voidg(
)
…在同乙個作用域裡顯式地兩次使用using namespace—對於新編寫的軟體,這是一種不應推薦的方式。
」(p.364)
1.「…可以在多個命名空間宣告中將各種名稱加進乙個命名空間中。例如:
namespace a
;namespace a
;
…允許命名空間的定義散布在多個標頭檔案和源程式檔案中。
」(p.365~366)
1.「考慮乙個老問題,乙個類的成員將遮蔽其基類中具有同樣名稱的成員:
classb;
classd:
public b
;void
f(d& d)
…可以通過乙個使用宣告,將b的f()引入到作用域:
classb;
classd:
public b
;void
f(d& d)
」(p.367)
1.「允許匿名的命名空間:
#include
namespace
intg()
}
除了不會與標頭檔案中的名稱產生過載之外,這種寫法等價於:
#include
static
int a;
static
voidf(
)static
intg()
簡單說:
namespace
等價於:
namespace unique_name
using
namespace unique_name;
在乙個作用域中的各個匿名命名空間都共享同樣的唯一名稱。特別是,在乙個編譯單元中所有的全域性匿名命名空間都是同乙個命名空間的一部分,而且它們又與其他編譯單元的匿名命名空間不同。
」(p.369)
1.「具有c連線的函式也可以放進乙個命名空間中:
namespace x
這就使具有c連線的函式使用就像是該命名空間的另乙個成員。例如:
voidh(
)
當然,在同乙個程式中,不能在兩個不同命名空間裡存在兩個同樣名稱的具有c連線的函式,因為它們將被解析到同乙個c函式(重名錯誤)。c語言的不安全的連線規則將使這種錯誤很難發現。」(p.370)
1.「在c++從c語言那裡繼承來的功能、技術和思想中也包括c的預處理程式–cpp。我原來就不喜歡cpp,現在也不喜歡它…c++為#define的主要應用提供了const、inline、template、namespace等替換方式…c++沒有為#include提供替代形式…留下的使#ifdef和#pragma。沒有#pragma我也能活,因為我還沒有見過乙個自己喜歡的#pragma…我很願意看到cpp被廢除。」(p.371~374)
《c 語言的設計和演化》筆記(一)
1.既然c 裡的class意味著使用者定義型別,為什麼我不直接稱它為type呢?選擇用class這個詞的基本原因是我不想發明新術語。p.27 2.像c語言中一樣,物件的分配可以有3種方式 在堆疊上 作為自動物件 在固定位址 靜態物件 或者在自由儲存區 在堆,或者說是動態儲存區 與c語言不同的是,c ...
讀書筆記 C 語言設計與演化
1 乙個好的語言工具的準則 對程式組織的支援 具備類分層結構,對併發的某種形式支援,對型別系統的強檢查 高效能 執行速度快,編譯整合程式簡單有效。高度可移植,多平台可執行 2 c 的很多設計角色根源於坐著對強迫人按某種特定方式行事的極度厭惡。c 被有意設計成能夠支援各種各樣的風格,而不是強調一條真理...
C 系列文章之《C 語言設計與演化》讀書筆記
一直以為自己的c 水平還可以,但是感覺只停留在理論階段,實際遇到問題時還不知所措,進而藉此機會在好好學習一下。學習理論同時以實踐為主,結合自己工作經驗將容易出錯的地方記錄下來,供以後備查。學習計畫如下 a c 語言設計和演化 b accelerated c c c 語言程式設計 d c primer...