2015-05-05 22 views
3

我發現一段代碼如下。何時使用預處理器指令來定義C++中的函數?

#define READWRITE READWIRTE 
#define READWIRTE(varType, varName, funName)    \ 
private: varType varName;         \ 
public: varType get##funName(void) const { return varName; }\ 
public: void set##funName(varType var){ varName = var; } 

READWIRTE(int, mSessionId, SessionId) 

我想知道爲什麼不以正常形式定義函數。我的意思是,像這樣:

private: 
    int mSessionId; 
public: 
    public int getSessionId() const; 
    public void setSessionId(int sessionId); 

然後定義這兩個函數。

什麼時候應該使用預處理器指令?

+3

這不是定義一個函數。 – juanchopanza

+1

當你懶惰時!#¤%&誰不關心可讀性。另外:''(void)'' – Biffen

+1

你期望什麼答案?隨便你怎麼做。 – Matt

回答

2

正如@ user258367所說,這個宏可以幫助你用public getter和setter聲明私有字段。

如果你有一大堆那些不具備,做低層次的編碼爲你的IDE,它可以是一個選項,因爲:

READWIRTE(int, mSessionId, SessionId) 

比完整的代碼更簡潔。

但是,除非它是在企業環境中一個常見的用法,並列入在許多項目中共享的.h,我不會使用它:

  • 寫第一個領域,以及後來的getter和setter似乎更常見的用法
  • 鼓勵總是有getter和setter,甚至一人useles(但你可能有其他的宏只讀,只寫)
  • 它讓你在隱含能見度public:這可能會造成混淆

    private: 
        int foo; // private, no need for getter or setter 
        READWIRTE(int, mSessionId, SessionId); 
        double bar; // is public ! 
    
    public: 
        void othermethod(); 
        ... 
    
1

看來這是一個用於在類上生成「屬性」的宏。作者很可能使用它作爲快捷方式,而不是手工輸入私有成員/訪問器/增變器。

2

這個宏將確保每個變量都能正確定義它的setter和getter。

這將有助於您的開發人員認爲每次寫變量,getter和setter都浪費時間的情況。他可以簡單地稱這個宏。如果你想要setter和getter,那麼對於做代碼檢查的人來說,這將更容易,因爲他/她將知道會發生什麼(在這種情況下它將是宏觀的)。

1

我看到了兩個很好的理由使用宏:

  • 喜歡這裏,作爲簡寫,以避免繁瑣的輸入;

  • 確保在不同平臺或代碼的不同變體之間的代碼的可移植性,當您不想將非可移植構造函數(函數調用)包含在額外函數中時。

1

請不要這樣做。

它完成的原因是它可以節省您一些打字的時間。巨大的缺點是它會嚴重干擾調試。假設您在代碼中可能包含錯誤的區域中看到對setSessionId的調用。您搜索setSessionId的定義。而你找不到它。源代碼中的任何位置都沒有該方法的定義。工具可能不夠聰明,無法指向READ_WIRTE宏。所以那時你完全被卡住了。與其花費5秒尋找方法定義,並且看到它只設置一個成員變量並且可能無害,而是花費年齡尋找函數的定義。

(有些人可能會爭辯說,你應該期望setSessionId只是設置一個成員變量,當你的代碼存在錯誤時不是這樣,你知道不符合你的期望)。

1

該代碼看起來旨在爲用戶提供簡單的向類中添加屬性的簡寫。乍一看,它似乎是一個有用的快捷方式來防止不必要的輸入。然而,簡單地在成員函數中添加getter和setter可能並不總是最好的路線,原因如下。

  1. 在這種情況下,幾乎沒有任何價值被添加到簡單添加公共成員變量,因爲函數只是設置或返回值。
  2. 這兩個函數中的其中一個可能不是必需的。例如,如果使用RAII,則該值設置爲對象構造,添加一個設置器可能不是必需的,或者實際上是不合需要的。
  3. 它可能完全不支持大對象或以有效的方式支持大對象。
  4. 它不會(目前的形式)是線程安全的。
  5. 除非使用此代碼也生成或使用類似的宏,在某些時候這些函數調用將被客戶端代碼調用,因此getters和setters必須手動編碼(即使他們不會不會嚴格地出現在頭文件中)並且...
  6. ...在通過源代碼查找定義時,調試將會更加困難,例如,setSessionId()它不會在任何地方找到。

儘管可以使用宏實現此操作,但使用宏的normal warnings也適用。結論是在走這條路線之前要三思。