2017-08-10 29 views
1

考慮下面的設計:如何在使用多態性時避免下滑?

class RawDataBase 
{ 
private:  
    std::string data; 
}; 

class RawDataA : public RawDataBase 
{ 
private:  
    int spec_data_for_a1; 
    int spec_data_for_a2; 
}; 

class RawDataB : public RawDataBase 
{ 
private:  
    int spec_data__for_b; 
}; 

class MessageBase 
{ 
private:  
    int x; 
    int y; 
    int z; 
public: 
    virtual void Decode(RawDataBase *raw) 
    { 
     // extract x,y,z from raw.data 
    } 
}; 

class MessageA : public MessageBase 
{ 
private:  
    int spec_data_for_a1; 
    int spec_data_for_a2; 
public: 
    /* Here raw must be RawDataA*/ 
    virtual void Decode(RawDataBase *raw) 
    { 
     MessageBase::Decode(raw); 
     RawDataA raw_data = static_cast<RawDataA*>(raw); 
     // extract spec_data_for_a1, spec_data_for_a2 from raw_data 
    } 
}; 

class MessageB : public MessageBase 
{ 
private:  
    int spec_data__for_b; 
public: 
    /* Here raw must be RawDataB*/ 
    virtual void Decode(RawDataBase *raw) 
    { 
     MessageBase::Decode(raw); 
     RawDataB raw_data = static_cast<RawDataB*>(raw); 
     // extract spec_data__for_b from raw_data  
    } 
}; 

我有一個設計問題,而解碼RawDataMessage

RawDataRawDataA & RawDataB)有兩種類型。 RawDataA將被解碼爲MessageA,而RawDataB將被解碼爲MessageBRawDataARawDataB都共享一些常用數據,因此RawDataBase被創建爲基類。 同樣適用於MessageAMessageB,源自。

然後,將一個虛擬Decode函數添加到中,以RawDataBase對象作爲參數。但在MessageAMessageB中有一些問題。對於MessageA,參數實際上應該始終爲RawDataA,因此必須在此完成壓鑄。但是有人說,在代碼中使用下拉式演員時必定存在一些設計問題。

所以我的問題是如何設計這裏的代碼,以避免羽絨被?

謝謝!

+0

'模板'似乎比繼承在這裏更好分解代碼。 – Jarod42

+0

你是否也指CRTP?或其他解決方案。謝謝! – xYZ

+0

不需要CRTP,一個簡單的模板類。 – Jarod42

回答

1

爲了在這裏避免停機投:

class MessageA : public MessageBase { 
    virtual void Decode(RawDataBase *raw) { ...} 
} 

您的代碼必須成爲這樣的事情:

class MessageA : public MessageBase { 
    virtual void Decode(RawDataA *raw) { ...} 
} 

這意味着必須以某種方式成爲:

class MessageBase { 
    virtual void Decode(RawDataA *raw){...} 
} 

這是可以做到使用這樣的模板:

class RawDataBase { /* ... */ }; 
class RawDataA : public RawDataBase { /* ... */ }; 
class RawDataB : public RawDataBase { /* ... */ }; 

template<typename T> 
class MessageBase { 

    using RawDataType = T; 

    // ... 

    virtual void Decode(RawDataType *raw){/* ... */} 

    // ... 

}; 

class MessageA : public MessageBase<RawDataTypeA> { 
    // ... 

    virtual void Decode(RawDataType *raw){/* ... */} 

    // ... 
}; 

class MessageB : public MessageBase<RawDataTypeB> { 
    // ... 

    virtual void Decode(RawDataType *raw){/* ... */} 

    // ... 
}; 
+0

酷!這解決了我的問題:-)感謝您的幫助! – xYZ

+0

它不是CRTP,它將用於'class Derived:public Base '。這是模板類的簡單繼承。 – Jarod42

+0

@ Jarod42你是對的,我的壞。我編輯了我的答案。謝謝 :) – wasthishelpful

相關問題