c++11設計理念——保證穩定性和兼容性

根據設計理念對c++11新特性進行劃分

保持與c99兼容

c++11對c99特性的支持納入了新標準中

  • c99中的預定義宏
  • __func__預定義標識符
  • __Pragma操作符
  • 不定參數宏定義以及__VA_ARGS__
  • 寬窄字符串連接
    預定義宏
    __ STDC_HOSTED __:編譯器的目標系統環境中包含完整的標準C庫,宏定 義是1 ,否則是0
    __ STDC __: C編譯器通常用這個宏的值來表示編譯器的實現是否和C標準一致。
    __ STDC_VERSION __: 表示所支持的C標準的版本4
    __STDC_ISO_10646 _:

__ func __ 預定義標識符:返回所在函數的名字 不過將__func__標識符作爲函數參數的默認值是不允許的。這是由於在參數聲明的時後,__ func __ 還沒定義。
__ Pragma 操作符
#pragma once 相當於

#ifndef THIS_HEADER
#define THIS_HEADER
// 一些頭文件的定義
#endif
相當於
_Pragma(“once”); #pragma 不能再宏中展開,所以_Pragma的力靈活性更高
變長參數的宏定義和 __ VA_ARGS __:
變長參數的宏定義:指的是在宏定義中參數列表的最後一個參數爲省略號…
而後者可以替換省略號所代表的字符串
寬窄字符串的連接
c++11表準的編譯器會將窄字符串轉換成寬字符串,然後再與寬字符串進行連接。

long long 整型

c++最大整型的改變就是多了long long
unsigned long long 和 unsigned long long int 是等價的
long long 整型可以在不同的平臺有不聽的長度,但至少是64位
要知道平臺long long 大小的方法就是查看 (<limits.h>)中的宏
有三個:
LLONG_MIN 最小long long 值
LLONG_MAX 最大 long long 值
ULLONG_MIN 最小 unsigned long long 值

擴展的整型

c++11中一共之定義了5種標準的有符號整型

  • signed char
  • short int
  • int
  • long int
  • long long int
    c++11規定:擴展的整型必須和標準類型一樣,有符號類型和無符號類型佔用同樣的大小的存儲空間
    c++是一種弱類型語言,當運算、傳參等類型不匹配的時候,整型間發生隱式的轉換,這個過程是整型的提升。
    進行隱式的整型轉換時候,低等級向高等級 有符號轉換成無符號
    原則是
    長度越大的整型等級越高 long long int 高於 int
    長度相同的情況下,標準整型 等級高於擴展整型 long long int 高於_ int64
    相同大小的有符號類型和無符號類型的等級相同,long long int 和 unsigned long long int

宏__cplusplus

__ cplusplus 這個宏通常被定義爲一個整型值,隨着標準的變化,一般會是一個比以往標準中更大的值
extern"c" 這樣的做法是成爲了c與c++中混用頭文件的典型做法
連接器可靠的對兩種類型的目標文件進行鏈接。
#ifdef __ cplusplus
extern “C”{
#endif
//一些代碼
#ifdef __ cplusplus
}
#endif

靜態斷言

斷言: 是將一個返回值總是需要爲真的判別式放在語句中,比如一個函數總是輸入在一定範圍內的參數,對參數使用斷言。
優點:通常斷言能夠幫助程序開發者快速定位那些違反了某些前提條件的程序錯誤。
在< cassert>或<assert.h>頭文件中提供 assert宏
定義NDEBUG 來禁用assert宏
斷言assert只有在程序運行是纔有效
爲了解決如何在編譯時斷言,則引出了所謂的“”“靜態斷言”
可以採用三種方法實現靜態斷言:
1.利用除0會導致編譯器報錯這個特性來實現靜態斷言
#define assert_static(e)
{
do {
enum {assert_static__ =1/(e) };
}while(0)

2.Boost庫內置的BOOST_STATIC_ASSERT 輸出的信息主要是sizeof錯誤
3. static_assert 接收兩個參數 :斷言表達式(必須是常量表達式) ,通常返回一個bool值 ;一個則是警告信息 寫一句警告的話,放在""裏面
如果程序員要的是運行時的檢查,用assert宏就行

noexcept修飾符和noexcept操作符

c++11中棄用了 throw() 動態異常聲明
若表示不會拋出異常,則用noexcept()取代了throw()
如果noexcept()表示拋出了異常,編譯器可以直接選用std::terminate()函數來終止運行,這比異常機制throw()的效率高,因爲異常機制帶來額外的開銷,比如函數拋出異常,會導致函數棧被依次的展開。
noexcept()修飾符有兩種形式,
直接在函數聲明後面加上關鍵字 noexcept
或者後面在加上 (常量表達式)
若常量表達式轉換成的bool類型值爲true 說明 不會拋出異常,false 拋出異常
若用於模板,很好的支持了泛型編程
一個類析構函數不應該拋出異常,c++11默認將delete函數設置成 noexcept 可以提高應用程序的安全性。
c++11中讓類的析構函數默認爲noexcept(true)的,若顯示的指定就會失去默認值。

快速初始化成員變量

c++98中“就地聲明”。
用= 初始化類中靜態成員變量,如果靜態成原變量不滿足常量性,則不可以就地聲明,而且即使是常量的靜態成原也只能是整型或者枚舉型才能就地初始化。
c++11中,允許非靜態成員使用= 或{ }進行就地的非靜態成原的初始化。初始化列表被保存下來,是否能把兩者結合使用呢?答案是可以的。只不過初始化列表 的效果總是優先於就地初始化。

非靜態成員的sizeof

在c++98中對非靜態成員變量使用sizeof是不能通過編譯的。
在c++11中可以使用。

擴展的friend語法

c++11對friend 關鍵字做了一些改進
在c++11中聲明一個類爲另外一個類的友元時,不在需要使用class 關鍵字
使用內置類型int 作爲模板參數的時候,people會被實例化爲一個普通的沒有友元定義的類型。
使用using定義類型別名和使用typedef的定義類的別名是完全一樣的。

final / override 控制

final關鍵字作用是使派生類不可覆蓋他所修飾的虛函數
c++中重載有一個特點,基類聲明爲virtual函數,之後的重載版本都不需要再聲明重載函數爲virtual 。編譯器可忽略。
虛函數描述符:override
派生類在虛函數聲明時使用override描述符,那麼該函數必須重載其基類中同名函數,否則代碼將無法通過編譯。

模板函數的默認模板參數

函數末班參數的選擇總是由函數的實參推導而來的。

顯示的實例化和外部模板的聲明

c++11是對外部模板 模板性能上的一個改進 extern
外部模板聲明 和顯式實例化差不多,只是多了extern關鍵字
在使用外部模板時注意:
如果外部模板聲明在某個編譯單元中,那麼與之對應的顯式實例化必須出現在另一個編譯單元中或者同一個編譯單元的後續代碼中,外部模板聲明不能用於一個靜態函數,可以用於類靜態成員函數,因爲靜態函數沒有外部鏈接屬性。
c++11中模板的顯示實例化定義 、外部模板聲明 和使用 對比 全局變量的定義,外部聲明和使用 的方式 ,不過相比於外部聲明變量,外部末班聲明不會有什麼問題。外部模板定義算作是一種針對編譯器的編譯時間和空間的優化手段。

局部和匿名類型做模板實參

要使用匿名結構體作爲模板參數,則可通過對匿名結構體做別名來實現。也可以用c++11獨有的decltype完成相應的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章