2012-02-28 34 views
1

基本上我今天發現自己編寫大量的代碼象下面這樣:「重定向」類成員函數?

#define VAL_1 0 
#define VAL_2 1 

class A { 

public: 
    void memberA(); 
    void memberB(); 

    ... 

    void write(uin32_t address); 

} 

void 
A:: 
memberA() { 

    this->write(VAL_1); 

} 

void 
A:: 
memberB() { 

    this->write(VAL_2); 

} 

... 

所以基本上,我有「漂亮」的名字memberAmemberB一些任務確實不僅調用同一個函數write有不同的觀點。值VAL_0VAL_1不一定知道使用我的課程進行編碼。 memberAmemberB背後的實施細節也沒有,儘管write可能會在某些時候公開。

基本上,現在我重複同一行代碼this->write(...)一遍又一遍。我正在尋找一種繞過此步驟並立即調用相應寫入的解決方案。一類傳遞函數參數有點像C++的構造函數從基類,可能與匹配參數的:

#define VAL_1 0 
#define VAL_2 1 

class A { 

public: 
    bool memberA() : write(VAL_1); 
    bool memberB() : write(VAL_2); 

    ... 

    bool write(uin32_t address); 

} 

我想知道是否有可能是一個在Boost.Bind或一些聰明的模板編碼讓我實現這種或那種事情?

感謝,

FROB

回答

2

沒有完全理解你在做什麼之後(我對涉及構造函數的最後一部分感到困惑),我想你可能會試圖讓自己的語法變得更加容易。

...怎麼樣簡單:

class A { 
public: 
    enum Value {val1, val2, val3, val4, etc}; 
    bool write(Value val); 
}; 

這是很好的,你正在試圖建立一個更簡單的語法,但你也必須避免整體性的危險。單片類是我堅信的東西,是面向對象設計中最常見的錯誤之一。 Sutter在C++ Coding Standards和gotw:http://www.gotw.ca/gotw/084.htm中詳細討論了這一點。

如果你有一個擁有100個成員函數的類,那麼你可能有80多個成員函數。

^想一想這段話。當你有這麼多的功能時,你的班級往往越來越難以管理。它還邀請其他開發人員繼續爲您的課程添加越來越多的內容,以便其設計從未最終確定。其結果是,每一個開發週期都是無盡的階級,隨着每一個開發週期的增長而不斷增長,並且看不到盡頭。這很容易成爲錯誤,效率低下,持續的公共接口修訂,單元測試中斷,以及它可能違背班級的一般重用和靈活性。當你爲每個值單獨設置一個函數時,你可以傳遞給另一個函數,那麼你正在危險地踏入這個領域。

想盡辦法避免句法冗餘通常是一個錯誤。不幸的是,在某些情況下,C++只需要更長的語法(使用C++ 11會更好)。你應該嘗試優化的是邏輯冗餘。這裏使用各種值調用write方法不涉及邏輯冗餘,語法開銷幾乎不會超過爲每個可能傳遞的值調用不同的函數。

如果這些函數只是簡化了傳遞各種值的語法,那麼您必須認識到,如果您處於生產環境中,您還在使用更多功能來擴展該類的公共接口,你可能必須單獨記錄和教導。努力以更少的錢做更多的事情,我想你會過得更好。

儘量保持這個monolithism作爲一個優先考慮。你甚至可以走那麼遠,扯起命名常量出來的類定義爲非成員,像這樣的:

class A { 
    bool write(uint32_t address); 
}; 

// elsewhere 
static const uint32_t address_val1 = ...; 
static const uint32_t address_val2 = ...; 
static const uint32_t address_val3 = ...; 

其實這沒有什麼不對的設計,事實上,它有更多的希望工程特點而不是那些擁有更多班級成員的班級成員,因爲班級成員與班級完全脫鉤,使得班級的維護更容易,其界面更容易教授和記錄,並且更有可能達到合理完成狀態。

+0

那麼,我明白這一點。然而,'memberA'和'memberB'將在子類中有不同的實現,所以使用你的解決方案我不能覆蓋這些... – FRob 2012-02-29 09:43:46

+0

我的建議是隻寫*寫*公共,而不是擁有memberA和memberB函數,如完全刪除這些函數,而只是讓客戶端寫my_a.write(address_val1),例如順便說一句,你是否試圖做這個優化?如果是這樣,在編譯器應用其優化之後,memberA和memberB通常沒有開銷,因此從處理器效率角度來編寫這些函數的成本實際上是零。如果你發現編寫這些函數乏味,那麼這是一個不同的事情......但使用宏來產生你的... – stinky472 2012-02-29 17:05:48

+0

類方法通常會被視爲黑客。它不會在正常的生產環境中對代碼進行審查,以便通過預處理器簡化已經像這樣的一行代碼。 – stinky472 2012-02-29 17:05:57

4

如果你讓你的memberX功能內嵌在類定義,如果你避免了重複this引用,那麼你沒有太多額外的寫:

你想要的(不正確)的語法:

bool memberA() : write(VAL_1); 

實際的(正確)的語法:

bool memberA() { return write(VAL_1); } 

如果你希望儘量減少您的重複的代碼,你可以使用預處理:

#define F(l, n) bool l() { return write(n); } 
F(memberA, VAL_1) 
F(memberB, VAL_2) 
#undef F 

此外,你可以使用預處理標記粘貼操作##

#define F(l, n) bool member##l() { return write(VAL_##n); } 
F(A, 1) 
F(B, 2) 
#undef F 
+0

嘿,謝謝你的建議。這也是我想到的,但我認爲這只是一種更智慧的方法。 :/ – FRob 2012-02-29 09:44:26