隨著C++的普及,標準的指定成了C++發展的必然趨勢。而制訂此一標準的工作是由ANSI (American National Standards Institute,美國標準學會)與ISO (International Standardization Organization,國際標準組織)進行。
ANSI規則中的許多新規則都是對初的C++進行的擴充。也可以不使用這些新的特征。這些新特征包括關鍵字mutable以及explicit。
有一些修改的潛在作用很大。現在ANSI規則鼓勵某些編程方法而拋棄其他一些編程方法。盡管在一段時間內不會放棄對老式編程方法的支持,但是有一些編程方法終是要被淘汰掉的——這意味著編譯器將給出警告并建議使用新的編程方法。遲早有會拋棄掉對這些舊方法的支持。
ANSI規則的主要改變包括:
(1)新的頭文件的載入方式
在ANSI/ISO的C++標準里,定義了一個名為std的namespace,并將許多類定義在這個namespace。
例如,舊方法載入頭文件 #include <iostream.h>
新方法則修改為 #include <iostream>
(2)執行時間類信息 RTTI(Run-Time type Inforamtion)
RTTI中文字面翻譯為執行時間類信息,也就是在執行時判別數據的類型,例如:判別模板被什么類型套用?
首先在使用typeid前,必須include名為typeid的頭文件。可以利用typeid判別某一變量的數據類型
int a;
if(typeid(a)==typeid(int)) // 判別a的數據類型是否為int
……
或者取得變量的數據類型的名稱 char *data_type=typeid(a).name() //輸出a的數據類型
(3)類型轉換
C語言對所有的情況都使用一種類型轉換運算符,在ANSI/ISO C++標準的草案中,新增了四種類型能夠轉換語法,分別針對四種特定的類型轉換需要,以取代傳統的類型轉換。新增的類型轉換語法能夠更精確地控制程序、減少程序錯誤的產生。這四種新的類型轉換運算符分別是:const_cast, dynamic_cast , reinteroret_cast, static_cast。
const_cast (去除const屬性)
const_cast操作符用來幫助調用那些應該使用而沒有使用const關鍵字的函數。換句話說,就是供程序設計師在特殊情況下將限制為
const成員函數的const定義解除,使其能更改特定屬性。
例如:void display_num(double *p)
{
printf(“The value is %2.3f\n”,*p);
}
const double x;
display_num(& x); //Disallowed! C++的規則禁止這樣調用,因為一個const指針通常不能傳遞給一個非const類型的參數
display_num(const_cast<double *>(& x)); //將& x由const double *類型轉換為double *類型。
[NOTE]:當使用const_cast操作符時,必須保證不改變指針所指向的數據。如果你使用const_cast操作符又設法改變指針所指向的數據,那么將使實際結果無法預料。
const double x=17.5;
double *p;
p = const_cast<double *> (& x);
*p = 33.2; // This operation is undefined!
dynamic_cast (程序運行時對類型進行的檢測)
在這四個新的運算符中間,只有dynamic_cast提供了新的功能。如果啟動了支持運行時間類型信息(RTTI),dynamic_cast可以有助于判斷在運行時所指向的對象的確切類型。它與typeid運算符有關。
使用dynamic_cast操作符有用的原因是一個基類的指針能夠指向許多不同的子類型(派生類),可以將被轉型為基礎類的對象還原成原來的類。不過,限于對象指針的類型轉換,而非對象變量。
class B
{
public:
virtual void func1(int);
};
class D: public B
{
public:
void func2(void);
};
void process_B(B *arg)
{ B *pb;
pb = dynamic_cast<D *>(arg);
if(pb) //如果arg指向類D或類D的派生類的對象,那么這個類型轉換是成功的。
pb->func2();
…
}
[NOTE]:當編譯此類型程序時,必須設定項目中有關C++語言的設定,否則編譯器將出現錯誤信息,而且會發生執行錯誤。點選project/setting選項,出現Project Setting對話框后,切換到C/C++標簽,然后點選Enable Run-Time Type Information(RTTI)復選框。
reinterpret_cast操作符將一個指針轉換成其他類型的指針,新類型的指針與舊指針可以毫不相干。通常用于某些非標準的指針數據類型轉換,例如將void *轉換為char *。它也可以用在指針和整形數之間的類型轉換上。
char a_char =’A’, * cp = & a_char;
void *vp;
vp=cp;
cout<<*(reinterprt_cast,char *>(vp)); // 輸出時將vp的類型由void* 轉換成char*
[NOTE]:reinterpret_cast操作符存在潛在的危險,除非有使用它的充分理由,否則就不要使用它。
例如,它能夠將一個int *類型的指針轉換為float *類型的指針,但是這樣很容易造成整數數據不能被正確地讀取。
static_cast (轉換成為相關的對象或者指針)
static_cast操作符能在相關的對象和指針類型之間進行類型轉換。有關的類之間必須通過繼承或者構造函數或者轉換函數發生聯系。
static_cast操作符還能在數字(原始的)類型之間進行類型轉換。
通常,static_cast操作符大多用在將數域寬度較大的類型轉換為較小的類型的情況。當轉換的類型是原始數據類型時,這種操作可以有效地禁止編譯器發出警告。
long i = 17;
short j = static_cast<short>(i);
同樣,可以沒有任何限制地將一個基類的指針轉換為一個派生類的指針。因為沒有執行運行時狀態檢查,你要保證實際的數據支持這個類型的轉換。這一點類似于dynamic_cast操作符。
還有一些其他的情況static_cast操作符能夠有效地被使用,但是這在大多數程序中是少見的。例如在A類中定義了一個到B類的類型轉換,在B類中定義了一個到int型的類型轉換。按照下面的操作類A的一個對象可以被轉換為int型。
A oa;
int i = static_cast<int>(static_cast<B>(oa));
(4)其他關鍵字
除了前面提到的關鍵字,ANSI規則支持mutable、explicit和bool:
關鍵字mutable與前面提到的const_cast 有異曲同工之處。它改變成員的聲明,甚至當成員是const對象的一部分,也可以對成員進行修改。
關鍵字explicit阻止構造函數進行轉換。
關鍵字bool定義一個數據類型,此數據類型只有2個值:真(true)和假(false)。
完全可以不使用mutable和explicit。除了支持bool數據類型之外,ANSI C++添加了兩個預定義的常量true與false,分別等于1和0。
(5)模板與例外處理
模板與異常處理是C++的兩個主要的特征。現在許多編譯器都支持這兩個特征,但是早期版本的C++并沒有這個特征。編寫一個通用的類或函數并可以在其中加入特殊的類型,所以模板技術可以是代碼重復使用。
除了支持使用關鍵字template定義新的模板之外,ANSI規則也列出了標準模板庫STL(Standard Template Library),在這個庫中包含許多通用的類。其設計的目的就是將程序設計里經常用到的基本數據結構和算法建成可供程序者套用的程序庫。
異常處理是用于響應運行時錯誤和其他事件的技術,它的用法要優于老式C庫函數raise和signal。例外處理(Exception Handling)是C++提供的錯誤處理機制。所謂的例外是Exception的字面翻譯,意指程序意料之外的情況,也就是在程序正常執行下,出現未被期待發生的狀況。
例外處理的機制主要有兩大部分:錯誤偵測區塊和錯誤處理區塊。
try
{ // 錯誤測區塊
throw(錯誤類型);
//如果發生錯誤用throw語句傳出錯誤
}
catch(錯誤類型一)
{ // 錯誤處理區塊}
catch (錯誤類型二)
{ // 錯誤處理區塊}
…
catch(…) //如果前面未列舉處理類型,則由此處處理區塊處理
{ // 錯誤處理區塊}
throw語句并不是只能丟出提示錯區信息的字符串,還可以丟出例外類的對象,所以針對例外處理,可以建立一個例外類,通過這些類協助處理程序的錯誤。在C++標準里,制訂了標準的例外處理類,它們都繼承于exception類,該類聲明了構造函數和析構函數,但不包括成員函數。這個基類有兩個子類(logic_error報告不能執行的錯誤;runtime_error報告無效的操作或不正確的結果),每個子類都對應一組通用異常。定義exception類的頭文件為exception頭文件,定義logic_error與runtime_error及其繼承類的頭文件為stdexcept。如果希望知道例外的錯誤信息時,只要調用例外對象的what成員函數。
(6)if 語句中變量的作用范圍
在ANSI C++中可以在if語句中聲明一個變量。該變量的作用范圍是整個if語句塊。
if(int j = 1)
{
cout<<j<<endl; //正確,定義了j
}
j=2; // Error,j超過了作用范圍
這個特征明顯的用處是控制由dynamic_cast返回的指針的作用范圍。在下面的程序中,if語句中定義了pd,所以只有在dynamic_cast成功時它才可用。
if (D *pd = dynamic_cast<arg>)
{ // 僅當arg指向了D對象時dynamic_cast才成功返回
// pd可以在語句中安全使用
}
pd->func2(); // Error!pd超出了作用范圍
因為轉換成功(因此返回一個非空值給pd),所以在if語句塊中使用pd是安全的。如果在if語句塊之外使用pd,在編譯時就會產生錯誤。這樣就可以在程序發布之前改正這個錯誤。這樣的后果是,如果只在一處定義了pd,編譯器將阻止在pd作用范圍之外使用它,因此也防止了在運行時出錯。
(7)具有枚舉類型的函數的重載
ANSI C++增強了聲明為枚舉類型的狀態;特別是重載函數時,可以將enum類型與其他整數類型區分開。而在C和C++的舊版本中,enum類型與int類型的參數聲明是可以互換的。
enum suit
{ clubs, diamonds, hearts, spades
};
void func1(int n)
{ cout<<”Inside func1(int)”<<endl;
}
void func1(enum card)
{ cout<<”Inside func1(suit)”<,endl;
}
函數調用為:func1(spades);
輸 出:Inside func1(suit)
(8)嵌入類的前向引用
class family
{
class father; //允許對father進行前向引用
char last_name[5];
…
class father //嵌入類的聲明
{
char first_name[10];
…
};
};
ANSI C++特征總結
更新時間: 2007-02-05 23:40:15來源: 粵嵌教育瀏覽量:1005
推薦閱讀
- ·湖北精實機電科技有限公司專場招聘會(長沙校區)
- ·信號量與互斥鎖在資源競爭中的協同控制機制
- ·粵嵌科技2025年中總結大會召開——擘畫產教融合新藍圖
- ·Linux字符設備驅動框架解析:file_operations的核心作用與實現
- ·廣東朝歌數碼科技股份有限公司專場招聘會
- ·深化產教融合,共筑技能人才培養新生態 —— 廣州華立學院到訪粵嵌從化校區為深化產教
- ·校企合作新突破 | 粵嵌科技與三亞學院共探產教融合新路徑
- ·粵嵌科技入選國家級職業數字展館聯合建設單位,賦能計算機程序設計員高技能人才培養
- ·嵌入式實時操作系統的性能優化與實現路徑
- ·校企攜手賦能教育!粵嵌科技助力海南科技職業大學探索 AGI 時代教學新范式