2011-09-13 105 views
1

我已經根據規範編寫了一個程序。
該規範有大約3種類型,每種類型在每一個點上的處理方式都不相同。C++多條件語句 - 合併

這意味着對代碼的可讀性或多或少,我寫它如下圖所示,現在我的問題是,如果你有例如聲明,豈不是很值得他們全部合併成一個「如果枚舉類型x「

我相信有一個程序已經在那裏已經做到了,但谷歌沒有幫我很多這個具體問題。提前感謝您的幫助。要實現

/* Point 1.15 Filling Customers bdate */ 

if(current.identifier == APPLE){ output.setValue(1.15, additionalObj.some.color)} 
if(current.identifier == PLUM){ output.setValue(1.15, otherObj.another.color) } 
if(current.identifier == GRAPE){ output.setValue(1.15, default::color) } 


/* Point 1.16 Filling Customers cash*/ 

if(current.identifier == APPLE){ do whatever} 
if(current.identifier == PLUM){ do whatever} 
if(current.identifier == GRAPE){ do whatever} 

結果:

if(current.identifier == APPLE){ output.setValue(1.15, additionalObj.some.color) 
           do whatever 
} 

等等,所以我可以將它們合併到1條語句自動而我仍然有可讀的代碼

編輯:我可能會誤導你,它實際上不是一個類型,它只是一個具有String標識符和SubObjects的對象,所以我不能使用多態。我已經調整了以上所以你可以看到我想達到什麼。

+5

由於您使用的是C++,爲什麼不只是使用OO功能(如多態)來處理這個問題呢? –

回答

3

基本多態性的方法:

enum Type { tX, tY, tZ}; 

struct Data 
{ 
    Type type; 
    int data_; 
}; 

class Processor 
{ 

public: 

    virtual void fillCustomersBDate(const Data& data) = 0; 
    virtual void fillCustomersCash(const Data& data) = 0; 

}; 

class XProcessor : public Processor 
{ 
    virtual void fillCustomersBDate(const Data& data) { /* X stuff */} 
    virtual void fillCustomersCash(const Data& data) {/* X stuff */} 
}; 
class YProcessor : public Processor 
{ 
    virtual void fillCustomersBDate(const Data& data) {/* Y stuff */} 
    virtual void fillCustomersCash(const Data& data) {/* Y stuff */} 
}; 

void process(const Data& data) 
{ 
    Processor* processor = processorForType(data.type); 
    // Do general stuff 
    processor->fillCustomersBDate(data); 
    // Do general stuff 
    processor->fillCustomersCash(data); 
    // Do general stuff 
    delete processor; 
} 

更可能的是,你會移動最主流的進入的基類。

+0

感謝您的解決方案,我的問題是,它將需要我每個創建200個函數,所以我將不得不寫每個對象600個方法,3個類型x 200函數 –

+0

@Oliver Stutz。創建這麼多方法並不是顯而易見的錯誤。如果不同的「類型」的方法真的不同,並且每個方法都有一些清晰的內容,比如「fillCustomersBDate」,那就去做吧。如果沒有方法調用的通用代碼,你可能能夠聚合一些。如果實現真的對於不同的「相同」,那麼可能會有其他基於模板的解決方案。我們需要看到更多真實的代碼更清晰。 – Keith

+0

感謝您的回答,對我來說,重要的是代碼執行得很好,有600種不同的方法是不行的,我可以通過讓if(x){做到這一點,並且這和這個ect}節省很多努力和系統性能。而不是if(x){做這個} if(x){做那個}等等。我知道你想查看代碼,但仍然需要一個簡單的東西,合併相同的條件語句,例如,如果(x)將只有一次,並且檢查此條件的所有內容都合併在內,以便檢查x的性能已安全 –

0

如果他們都是不同的,你可以把它們分成各個部分,如:

if (type x) 
    processX1v1_thru_1v15(); // will do all steps 1.1 thru 1.16 for type x 
else if (type y) 
    processY1v1_thru_1v15(); // will do all steps 1.1 thru 1.16 for type y 
: : : 
and so on. 

但是你可能要考慮的多態性,這將允許您指定一個不同的「無所謂」每個類/類型。你可以做像這樣的東西:

obj.doWhatever1_01(); // calls obj-specific method depending on type. 
obj.doWhatever1_02(); 
: : : 
obj.doWhatever1_16(); 
5

閱讀關於C++類繼承和多態如果你還沒有理解它們。 C++的這兩個特性將提供更加優雅的方式來解決您的問題。

+0

@(Upvoters):只想說,感謝所有upvoters這個簡短的,無例證的答案。您的讚譽讓我有幸在「無處不在」評論。請做出積極的迴應,因爲他提供了一個簡單的例子。 – ksming

1

有兩種方法可以做到這一點:第一種方法是通過多態行爲(通過虛函數或類型參數化);第二種是switch的類型。

對於第一個中,每個類型的可以從一個共同的(可能是抽象的)基類繼承:

class Base 
{ 
public: 

    virtual void DoSomething() =0; 

}; 

class A : public Base 
{ 
public: 
    void DoSomething() 
    { 
     cout << "I'm doing something from A!" << endl; 
    } 
}; 

class B : public Base 
{ 
public: 
    void DoSomething() 
    { 
     cout << "I'm doing something from B!" << endl; 
    } 
}; 

這種方式,可以簡單地使用Base &類型,Base *的變量,或任何智能指針Base(例如shared_ptr<Base),然後在該變量上調用DoSomething方法。將根據變量的運行時類型調用DoSomething的正確實現(因爲DoSomething是一種虛擬方法)。

實現類似行爲的另一種方法是通過模板。它以類似的方式作爲第一個建議使用,但你並不需要一個基類和方法不必是虛擬的:

class A 
{ 
public: 
    void DoSomething() 
    { 
     cout << "I'm doing something from A!" << endl; 
    } 
}; 

class B 
{ 
public: 
    void DoSomething() 
    { 
     cout << "I'm doing something from B!" << endl; 
    } 
}; 

然後處理操作的功能可以被定義是這樣的:

template<typename T> 
void PolymorphicDoSomething(T variable) 
{ 
    T.DoSomething(); 
} 

像這樣使用:

A a; 
PolymorphicDoSomething(a); 

當然,這個例子是有點做作,但是這是基本的想法,並且可以根據situatio是非常有用的ñ。

另一種可能性是基本上做你現在正在做的事情,但是用一個switch聲明而不是幾個if聲明。如果變量的類型存儲爲enumint,你可以使用一個開關來有效地確定哪些操作執行:

enum VariableType 
{ 
    TypeA, 
    TypeB, 
    TypeC, 
    // etc. 
}; 

//... 

switch(variable_type) 
{ 
case TypeA: 
    DoSomethingForA(); 
    break; 
case TypeB: 
    DoSomethingForB(); 
    break; 
case TypeC: 
    DoSomethingForC(); 
    break; 
// etc. 
} 

但我懷疑,這真的是比任何使用虛擬方法更有效。另外,虛擬方法更具可管理性 - 爲了擴展功能,您必須簡單地聲明另一個類,並且您已擁有的所有代碼都可以應付它。在開關的情況下,無論您檢查變量的類型,都必須添加一個case語句。所以我會在這種情況下堅持使用虛擬方法。

+0

效率正是我的問題,iam試圖擺脫重複的控制機制,而不是建立更多的方法調用等。例如(if(x == true),do x,if(x == true),做那個,它應該全部在一箇中,一旦x == true和所有子語句,這就是爲什麼我要求一個合併工具,它可以自動重新編寫我的代碼,這樣我就可以保持簡單的可見代碼 –