2012-11-03 40 views
1

成像的類,它是做以下的事情避免C++類方法中的代碼重複?

class AClass 
{ 
    AClass() : mode(0) {} 
    void a() 
    { 
     if (mode != 0) throw ("Error mode should be 0"); 
     // we pass the test, so now do something 
     ... 
     mode = 1; 
    } 
    void b() 
    { 
     if (mode != 1) throw("Error mode should be 1"); 
     // we pass the test, so now do something 
     ... 
    } 
    int mode; 
}; 

類包含許多方法(很容易超過20),以及這些方法,我們需要做的模式值檢查這顯然是一個個很多代碼重複。此外,我們可以確定兩種類型的方法,那些在模式!= 0時將拋出錯誤的方法,以及在模式!= 1時拋出錯誤的方法。可以以某種方式將這些方法分爲兩類(類別A =如果模式!= 0,則拋出一個錯誤的方法)以及如果模式!= 1拋出錯誤的方法的類別B)?

編輯:縱觀當前的答案,我意識到我制定問題的方式,問題可能不夠清楚。我想避免的是不得不在每個類的方法中調用一個函數。無論我們在方法的開始處編寫代碼還是將此代碼放入函數並調用此函數都不是問題。問題是我們是否可以一起避免這一切。是否有一種技術可以幫助根據某些上下文自動檢查對某個方法的調用是否有效。

AClass實際上是一個API在我的項目中。 a(),b()等是程序員可以調用的一些函數,如果他/她想要使用API​​,但其中一些方法只能按照某種精確的順序調用。例如,您可以在代碼中看到,一個()設置模式= 1,所以程序員可以做這樣的事情:

a(); // mode = 0 so it's good 
b(); // mode = 1 so it's good 

但是這個代碼需要故障(它會編譯過程,但在執行時我需要拋出一個錯誤提的是,其中b()被調用的情況下是錯誤的。

b(); // mode 0 so it won't work 
a(); // it will compile but throw an exception 

我想看看是否有任何模式可以工作,這樣做的,但不能在所有發現任何東西。它似乎是不可能的對我來說,我相信唯一的選擇就是編寫必要的代碼。任何人都可以提出一些建議嗎?非常感謝。

+0

嘗試尋找Aspect Oriented Software Development http ://en.wikipedia.org/wiki/Aspect-oriented_software_development – imreal

+4

您可以將錯誤引發代碼放入一個特殊的函數中,該函數將接受方法名稱和模式作爲參數來執行右引號。然後你可以在方法的開頭調用這個函數。 –

回答

0

嗯,我想最簡單的解決辦法是定義這樣的宏或一些內聯函數:

#define checkErrorMode0(x) \ 
    if ((x) != 0) throw ("Error mode should be 0"); 
#define checkErrorMode1(x) \ 
    if ((x) != 1) throw ("Error mode should be 1"); 

// or, probably within your class 
inline void checkErrorMode0(int x){ 
    if (x != 0) throw ("Error mode should be 0"); 
} 

inline void checkErrorMode1(int x){ 
    if (x != 1) throw ("Error mode should be 1"); 
} 

所以,你可以簡單地調用那些需要它們的函數內部的這些方法之一。

但是最有可能的是你想要做的更優雅的解決方法。

+0

感謝這個答案,但這並不能避免你仍然需要在類的方法中調用檢查方法的事實。問題在於,這是否是避免這種情況的方式。我意識到原來的問題不是很清楚。 – user18490

3

只需添加私有成員函數:

void assert_mode_0() { 
    assert_mode(0); 
} 

void assert_mode_1() { 
    assert_mode(1); 
} 

void assert_mode(int m) { 
    if (mode != m) 
     throw msg[m]; 
} 

msg一個合適的定義,當然。

2

除了在專門的方法中實施檢查(一個很好的建議),您還可以考慮將AClass中的行爲分解爲兩個不同的類,或將特定部分委託給一對新的類。如果mode對於實例是不變的(這在示例中),這看起來特別合適。

+0

謝謝你的回答。是的,我想過把支票放在一個單獨的函數中。它通常使用通常使用MACROS的代碼完成,我知道它不一定是最好的。但是,仍然有必要在每個方法的開始處插入對此函數的調用。 'mode'並不是真的不變。當你調用()模式被設置爲1.所以方法可以改變'mode'的值,該值用於跟蹤API調用的狀態。 – user18490

+0

「除非您考慮重新評估您的設計,否則仍需要插入呼叫」。 –

0

尋找到的問題有點多後,似乎最接近有用的答案是(尼克):

嘗試尋找到面向方面的軟件開發en.wikipedia.org/wiki/Aspect-oriented_software_development - 尼克

的維基百科頁面是不容易閱讀,不提供C++例如,使其保持非常抽象的在第一,但如果搜索面向方面編程和C++,你會發現實例鏈接。

它背後的想法(它只是一個非常快速的總結)就是找到一種方法來爲課堂添加「服務」或「功能」。這些服務尤其可以在編譯時通過使用模板來添加。這是我直觀地嘗試解決我的問題的嘗試,我很高興看到這種技術已存在多年。

這份文件是一個很好的參考:

面向方面編程& C++由克里斯托弗·迪金斯,08月01日,2004年

而且我發現這個鏈接以實例來理解這個概念有用:

Implementing Aspects using Generative Programming by Calum Grant.