程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 改善C++代碼的學習筆記2

改善C++代碼的學習筆記2

編輯:C++入門知識

1、使用typedef與#define提高可讀性
     對於某些復雜難懂的指針,如void (*p[10]) (void(*)()),誰知道這什麼東西?第一個括號中的*p[10]是指針數組,數組中的指針指向以void(*)()為參數的函數,而這個參數void(*)()又是一個指向無參數、無返回的函數指針。對於這些可讀性太糾結的東西,我們可以這樣來:typedef void (*pfv)()聲明無參無返回的函數指針,typedef void (*Keypoint)(pfv)聲明指向參數為pfv且無返回的函數指針,Keypoint p[10],終於搞定。
    在此處得說明一下,如果有這麼兩句typedef int* PINT與#define PINT int*的話,請注意,PINT p1,p2可能會讓你失望了。如果用的是typedef那會有兩個指針,如果是#define會有一個指針與一個整型變量。原因在於typedef一定的封裝性。
2、優先使用前綴操作符
    這裡以自增運算符為例,有能力的同學可以考慮從匯編的角度去比較一下,這裡從表面來看看。運行操作符前編譯器要去尋找相關的函數,不論前綴還是後綴,都是只有一個參數。為了區別,C++規定後綴形式有一個int型的參數,由編譯器傳遞一個0給該函數。那麼我們來比較一下兩者的區別吧:
[cpp]
//成員函數重載 
<類型> ClassName::operator ++();//前綴 
<類型> ClassName::operator ++(int);//後綴 
//非成員函數重載 
<類型> operator ++(ClassName&);//前綴 
<類型> operator ++(ClassName&,int);//後綴 
//後綴,構造臨時對象保存原值,自增,返回臨時對象 
//前綴,自增,返回 
     雖然可能效率上相差不大,但既然有省事的好辦法,何樂而不為呢?
3、區分new的三種形態
    new operator/operator new/placement new三種形態。可能我們常見的就是類似於int *ptr=new int類的寫法,同時我們也曾寫下過classname *ptr=new classname(……)創建一個對象,這就是new operator向內存進行申請。但申請內存又調用operator new,有點重載函數的意思,即void* operator new(size_t size)。而最後一種placement new是C++標准庫的一部分,用它來選擇合適的構造函數,如果想對未初始化的內存進行處理取得想要的對象,就這樣干吧:
[cpp]
#include <new> 
#include "classA.h" 
int main() 

       void *s=operator new ( sizeof(A) ); 
       A *p=(A*) s; 
       new (p) A(2012);//神奇的使用方法 
       …… 
       return 0; 
}              
</new> 
     真的是哥第一次見到這種東西,new (p) A(2012)在特定的內存上用特定的構造函數創建了一個對象,希望自己手動管理內存就用placement new。總結一下:1、在堆上建立對象,用new operator實現;2、僅僅分配內存,不干其它事,operator new,當然,不滿意的話自己重載一個;3、已有內存建立對象,placement new,通常不這麼干。
4、正確處理new的失敗
    面對new的失敗,平日裡常用if(!ptr){……}等語句。雖然至今沒見到過它申請失敗的樣子,但是對於現在的new而言,它並不會返回一個NULL的指針,反而是拋出一個std::bad_alloc的異常,那麼我們就應該采取新式的捕捉異常了:try{int* ptr=new int;……}catch(std::bad_alloce){return false;}。當然了,古老的編譯器仍會有返加NULL的情況,但新式的編譯器……呵呵,哥沒試過。。。
5、掌握定義變量的時機
    C++允許在任意位置定義變量,在遇上定義時,調用相關的構造函數,消去時也會調用其相關的析構函數。在使用變量時,盡量避免其作用域的膨脹,不僅有效減少變量名污染,同時還有利於他人閱讀理解。VC6.0中一個與VC2010明顯的區別在於for(int i=0;i<N;i++),這裡變量i的作用域在兩個環境下是不一樣的!總之,推遲變量的定義。
6、防止重復包含頭文件
    平時要#include “classA.h”時,萬一這裡面包含的與現有的發生重復,那就出錯了。常用的辦法是#ifdef <project>_<path>_<file>_h  #define ……,當然了,還有一種#pragma once的方法。編譯器每次編譯時都要打開頭文件才可判定是否有重復定義,故大項目裡,#ifdef使編譯時間較長,而#pragma once的方式由編譯器提供,它保證同一個文件不會被包含多次(同一個文件是指物理上一,不是指內容相同的),這種方法在兼容性方面貌似表現不是很好,故常用前者的方法。




摘自 自習室

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved