青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Shuffy

不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19
本文源自:http://m.shnenglu.com/tiandejian/archive/2007/04/04/ECPP_02.html

第2項:    盡量使用 const 、 enum inline ,避免使用 #define

這一項似乎叫做“盡量把工作交給編譯器而不是預編譯器”更恰當,因為 #define 的內容不應該屬于語言自身的范疇。這是 #define 的眾多問題之一,請看下面的代碼:

#define ASPECT_RATIO 1.653

編譯器也許根本就接觸不到這個符號名 ASPECT_RATIO ,它在編譯器對源代碼進行編譯以前也許就被預處理器替換掉了。于是, ASPECT_RATIO 這一名字很可能不會列在符號表中。如果你在代碼中使用了這常量,也許就會遇到一些很不容易察覺的錯誤,而往往你又很難找到問題所在,因為出錯信息只會涉及 1.653 ,而對 ASPECT_RATIO 則只字不提。如果 ASPECT_RATIO 是在某個你不知情的頭文件中定義的,那么尋找 1.653 的出處對于你來說就是大海撈針了,你將在跟蹤這一數值上浪費很多時間。在符號調試器中同樣的問題也會出現,原因和上述問題是一致的:你在編程時使用的名字可能沒有加入符號表中。

解決的辦法是:使用常量來代替宏定義:

const double AspectRatio = 1.653; // 宏的名字通常使用大寫字母,

                                    // 于是常量名這樣定義

作為語言層面的常量, AspectRatio 最終會被編譯器所看到,并且會確保進入符號表中。另外,對于浮點數而言,使用常量較 #define 而言會生成更小的目標代碼。這是由于預處理器會對目標代碼中出現的所有宏 ASPECT_RATIO 復制出一份 1.653 ,然而使用常量 AspectRatio 時永遠不會多于一份。

在使用常量代替 #define 時有兩個特殊情況值得注意。第一個是要把指針定義為常量。因為常量定義一般都放在頭文件中(許多不同的源碼文件會包含這些頭文件),要將指針定義為 const 的,這一點很重要,通常情況下也要將指針所指的內容定義為 const 。比如說,在一個頭文件中定義一個 char* 的字符常量時,你需要寫兩次 const

const char * const authorName = "Scott Meyers";

3 中我將向您全面介紹 const 的含義和用法,尤其是在其與指針混合使用時的一些細節問題。但是,在這里提醒你使用 string 對象要比使用其祖先“ char* ”好得多,知道這一點是很有意義的。上述的 autherName 最好以這樣的形式定義:

const std::string authorName("Scott Meyers");

第二個特殊情況關系到類內部的常量。為了將常量的作用域限制在一個類里,你必須將這個常量作為類的成員;為了限制常量份數不超過一份,你必須將其聲明為 static 成員:

class GamePlayer {

private:

 static const int NumTurns = 5;      // 常量聲明

 int scores[NumTurns];               // 該常量的用法

 ...

};

上面你所看到的是 NumTurns 的聲明,而不是定義。通常情況下, C++ 要求你為所有要用到的所有東西做出定義,但是這里有一個例外:類內部的靜態常量如果是整型(比如整數、字符型、布爾型)則不需要定義。只要你不需要得到它們的地址,你可以只聲明它們而不提供定義。如果你需要得到類常量的地址;或者即使你不需要這一地址,而你的編譯器錯誤地堅持你必須為這個常量做出定義,這兩種情況下你應該以下面的形式提供其定義:

const int GamePlayer::NumTurns;     // NumTurns 的定義,

                                    // 下邊會告訴你為什么不為其賦值。

你應該把這段代碼放在一個實現文件中。這是因為類常量的初始值已經在其聲明的時候給出了(比如說, NumTurns 在聲明時就被初始化為 5 ),而在定義的時候不允許為其賦初值。

順便要注意一下,你不可能使用 #define 來創建一個類內部的靜態常量,這是因為 #define 不關心域的問題。一旦定義了一個宏,在編譯時它將影響到所有其它代碼(除非你在某處使用 #undef 取消了這個宏的定義)。這不僅意味著 #define 不能用來定義類內部的常量,同時還說明它無法給你帶來任何封裝效果,也就是說,“私有的” #define 這類東西是不存在的。然而 const 數據成員可以得到封裝, NumTurns 就是一個例子。

早期的編譯器可能不會接受上面代碼的語法,這是因為那時候在聲明一個靜態的類成員時為其賦初值是非法的。與此同時,只有整型數據才可以在類內部進行初始化,并且只有常量才能得到初始化。在這種情況下不能使用上述的語法,你可以在定義的時候為其賦初值:

class CostEstimate {

private:

 static const double FudgeFactor;      // 靜態類常量的聲明

 ...                                  // 應在頭文件中進行

};

 

const double                             // 靜態類常量的定義

 CostEstimate::FudgeFactor = 1.35;     // 應在實現文件中進行

上面幾乎是你所要了解的全部內容了。但是在某時刻還有可能會發生一個小的意外:當你在編譯一個類的時候,你可能需要這個類內部的一個常量的值,比如說前述的 GamePlayer::scores 數組的聲明(編譯器可能會堅持在編譯時了解數組的大?。?。編譯器在這時違背了為類內部的靜態的整型常量賦初值的規范,那么有什么辦法補救呢?你可以使用“ enum 黑客手段”(這是愛稱,不帶有蔑視色彩)。這一技術利用了這一事實:枚舉類型數據都是 int 型的,所以 GamePlayer 也可以這樣定義:

class GamePlayer {

private:

 enum { NumTurns = 5 };       // enum 黑客”

                              // 使 NumTurns 成為一個符號名,其值為 5

 

 int scores[NumTurns];       // 可以正常工作

 ...

};

從許多角度講,了解 enum 黑客手段是很有好處的。首先, enum 黑客的行為更像一個 #define 而不是 const ,在某些情況下這更符合你的要求。比如說,你可以合法地取得一個 const 的地址,但是取 enum 的地址則是非法的,而去取 #define 的地址同樣不合法。如果不想讓其他人得到你的整形常量的指針或引用,那么使用枚舉類型便是強制實施這一約束的一個很好的方法。(參見第 18 項,那里介紹了使用編碼手段強制實現設計約束的更多信息。)粗心大意的編譯器也許會為這類對象分配多余的內存,但你也一定不會情愿。與 #define 類似, enum 不會帶來不必要的內存開銷。

了解 enum 黑客的第二個用處純粹是實用主義的。許多代碼都在這樣做,所以你看到它時必須要認得。事實上, enum 黑客是模板元編程的一個基本技術。(參見第 48 項)

回到預處理器的問題, #defined 另一個用法(這樣做很不好,但這非常普遍)就是將宏定義得和函數一樣,但不會帶來函數調用的開銷。下面例子中的宏定義使用 a b 更大的參數調用了一個名為 f 函數:

// 使用 a b 更大的一個調用函數

#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

這樣的宏會帶來數不清的缺點,想起來就讓人頭疼。

無論什么時候,只要你寫下了這樣的宏,你必須為宏內部所有的參數加上括號。否則,其他人在某些語句中調用這個宏的時候總會遇到麻煩。即使你做了正確的定義,古怪的事情也會發生:

int a = 5, b = 0;

 

CALL_WITH_MAX(++a, b);          // a 自加兩次

CALL_WITH_MAX(++a, b+10);       // a 自加一次

在這里,調用 f 以前 a 自加的次數竟取決于它和誰進行比較!

幸運的是,你不需要把精力放在這些毫無意義的事情上。你可以使用內聯函數的模板,此時你可以得到宏的高效,并且一切都是可預知的,類型安全的:

template<typename T>

inline void callWithMax(const T& a, const T& b)

// 因為我們不知道 T 的類型是什么,因此我們通過引用傳遞 const 參數。參見第 20

{

 f(a > b ? a : b);

}

這一模板創建了一族函數,其中每一個函數都會得到同一類型的兩個對象,使用其中較大的一個來調用函數 f ??梢钥吹?,在函數內部不需要為參數加括號,不需要擔心參數會被多次操作。與此同時,由于 callWithMax 是一個真實的函數,它遵循作用域和訪問權的規則,比如類可以擁有私有的內聯函數。然而宏在這些問題上就望塵莫及了。

C++ 為你提供了 const 、 enum inline 這些新特征,預處理器(尤其是 #define )的作用就越來越小了,但是這并不是說可以完全拋棄它。 #include 仍是程序中的主角, #ifdef/#ifndef 在控制編譯過程還有著舉足輕重的地位。說“預處理器該退休了”還為時過早,但是你還是要經常給它放放長假。

需要記住的

對于簡單的常量,應該盡量使用 const 對象或枚舉類型數據,避免使用 #define 。

對于類似程序的宏,盡量使用內聯函數,避免使用 #define 。

 

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大片91| 午夜视频在线观看一区| 一区二区三区无毛| 激情国产一区二区| 亚洲电影激情视频网站| 国产日本欧洲亚洲| 韩国免费一区| 在线观看久久av| 亚洲日本中文字幕免费在线不卡| 91久久精品日日躁夜夜躁欧美| 亚洲成色999久久网站| 亚洲福利国产精品| 日韩一级大片在线| 欧美一区日韩一区| 欧美激情片在线观看| 亚洲日本欧美天堂| 亚洲视频一区在线| 久久精品国产综合| 欧美三级韩国三级日本三斤| 国产欧美日韩三级| 亚洲国产三级| 性色一区二区三区| 欧美电影资源| 亚洲综合电影| 欧美国产1区2区| 国产欧美日韩亚洲精品| 91久久国产综合久久91精品网站| 亚洲一区二区av电影| 久久综合九色欧美综合狠狠| 亚洲激情影院| 欧美制服丝袜第一页| 欧美日韩国产美女| 亚洲欧美综合一区| 国产午夜精品视频免费不卡69堂| 国产亚洲欧洲一区高清在线观看| 怡红院精品视频| 亚洲一区二区三| 欧美a级片一区| 在线综合亚洲欧美在线视频| 久久琪琪电影院| 国产精品女人久久久久久| 亚洲黄色精品| 美女精品国产| 久久久www成人免费无遮挡大片| 欧美日产国产成人免费图片| 好吊妞**欧美| 欧美在线视频在线播放完整版免费观看| 亚洲第一福利在线观看| 久久成人一区二区| 国产精品青草久久| 一本大道久久a久久综合婷婷| 久热精品视频| 亚洲综合另类| 国产精品vvv| 一区二区三区www| 亚洲美女在线看| 欧美精品一区二区久久婷婷| 亚洲国产精品久久人人爱蜜臀| 久久久久久久国产| 欧美在线视频日韩| 狠狠久久婷婷| 麻豆精品精华液| 久久久久久久综合| 在线观看福利一区| 欧美大片免费观看| 欧美大片免费久久精品三p| 亚洲福利视频网| 欧美激情中文字幕在线| 久久久国产成人精品| 红桃视频欧美| 欧美+亚洲+精品+三区| 久久久精品国产一区二区三区| 国语对白精品一区二区| 久久一日本道色综合久久| 久久精品国产第一区二区三区最新章节 | 国产精品久久久对白| 亚洲日本国产| 日韩一级精品| 国产欧美 在线欧美| 久久久91精品国产一区二区精品| 欧美在线黄色| 亚洲激情在线观看| 亚洲色图综合久久| 狠狠干成人综合网| 亚洲日本成人网| 国产美女一区| 麻豆久久精品| 国产精品白丝黑袜喷水久久久| 欧美一级久久久久久久大片| 亚洲特色特黄| 久热精品在线视频| 欧美成人精品高清在线播放| 中文在线不卡| 欧美一区二区三区日韩视频| 亚洲国产欧洲综合997久久| 亚洲日本无吗高清不卡| 国产精品国产成人国产三级| 久久黄色小说| 免费一区视频| 欧美中文字幕不卡| 欧美夫妇交换俱乐部在线观看| 亚洲一区二区三区四区五区黄| 香蕉久久一区二区不卡无毒影院| 亚洲大片免费看| 亚洲私人黄色宅男| 亚洲国产91| 亚洲欧美日韩精品久久奇米色影视 | 亚洲欧美在线aaa| 亚洲人成网站在线播| 欧美日韩国产综合久久| 午夜精品国产更新| 欧美大尺度在线| 久久精品论坛| 欧美日韩国产免费| 美女网站在线免费欧美精品| 欧美色图麻豆| 亚洲高清免费视频| 国产日韩专区| 一区二区三区欧美激情| 亚洲国产精品悠悠久久琪琪| 亚洲免费中文字幕| 亚洲三级影院| 香蕉视频成人在线观看| 日韩一区二区久久| 午夜性色一区二区三区免费视频| 99精品视频免费| 久久久久久婷| 久久五月婷婷丁香社区| 国产美女精品一区二区三区| 亚洲美洲欧洲综合国产一区| 亚洲国产美女久久久久| 久久久久国产一区二区三区| 久久国产主播| 国产欧美日韩中文字幕在线| 在线视频欧美日韩| 宅男噜噜噜66一区二区| 欧美高清视频www夜色资源网| 欧美电影在线| 亚洲人精品午夜在线观看| 久久久久久久一区二区三区| 另类av导航| 亚洲国产高清在线| 欧美第十八页| 亚洲精品一区二区三区av| 亚洲美女在线一区| 欧美日韩岛国| 一区二区三区免费观看| 亚洲综合精品一区二区| 国产精品免费视频观看| 狼人天天伊人久久| 亚洲欧美日韩人成在线播放| 正在播放欧美视频| 欧美日韩中文在线| 在线视频精品| 欧美在线影院| 精品福利av| 欧美精品成人一区二区在线观看| 亚洲国产精品精华液网站| 亚洲理论在线| 国产精品久久久久久久久搜平片 | 亚洲精品国产视频| 欧美久久一区| 亚洲午夜一区二区| 久久精品日韩欧美| 亚洲国产欧美一区| 国产精品久久久久av免费| 亚洲欧美日韩电影| 久久艳片www.17c.com| 亚洲美女尤物影院| 国产欧美日韩在线视频| 欧美成人精品| 亚洲欧美久久久| 美女脱光内衣内裤视频久久网站| 亚洲成色精品| 国产精品美女一区二区| 久久综合九色综合网站| 一本一本a久久| 免费人成精品欧美精品| 亚洲一区二区黄色| 亚洲成人在线观看视频| 国产精品扒开腿做爽爽爽软件| 久久久www成人免费毛片麻豆| 亚洲另类自拍| 免费短视频成人日韩| 亚洲欧美中文另类| 亚洲日本视频| 国产在线拍揄自揄视频不卡99 | 欧美jizz19性欧美| 亚洲一区二区三区中文字幕在线 | 欧美国产日韩精品| 久久人人97超碰人人澡爱香蕉| 欧美国产精品久久| 欧美在线观看视频在线| 99视频+国产日韩欧美| 狠狠色丁香婷婷综合| 国产精品福利av| 欧美激情一区二区三区蜜桃视频| 午夜精彩视频在线观看不卡 | 久久精品日韩欧美| 亚洲免费在线观看视频|