2014-03-06 107 views
4

我有一個基類,目前我有一個名爲get_value()的方法,它應該返回適​​當地轉換爲各種基元數據類型的值。因爲,我們不能有這僅返回類型不同的虛擬方法,我必須做到以下幾點:虛擬功能設計問題

virtual void get_value(unsigned int index, unsigned char & r) const = 0; 
virtual void get_value(unsigned int index, char & r) const = 0; 
virtual void get_value(unsigned int index, unsigned short & r) const = 0; 
virtual void get_value(unsigned int index, short & r) const = 0; 
virtual void get_value(unsigned int index, unsigned int & r) const = 0; 
virtual void get_value(unsigned int index, int & r) const = 0; 
virtual void get_value(unsigned int index, float & r) const = 0; 
virtual void get_value(unsigned int index, double & r) const = 0; 

這是從一個維修點很煩人,也是使用是有點尷尬的用戶做這樣的事情:

unsigned char v; 
obj->get_value(100, v); 

不管怎麼說,事實上,所有的子類必須覆蓋每個這些類型是煩人。我想知道是否有人有任何建議,以避免這種情況,或以某種方式通過只有一個虛擬功能以一種更緊湊的方式做到這一點。

一個子類可以是這樣的:

void get_value(unsigned int index, unsigned char & r) const {get<unsigned char>(index, r);} 
void get_value(unsigned int index, char & r) const {get<char>(index, r);} 
void get_value(unsigned int index, unsigned short & r) const {get<unsigned short>(index, r);} 
void get_value(unsigned int index, short & r) const {get<short>(index, r);} 
void get_value(unsigned int index, unsigned int & r) const {get<unsigned int>(index,r);} 
void get_value(unsigned int index, int & r) const {get<int>(index,r);} 
void get_value(unsigned int index, float & r) const {get<float>(index,r);} 
void get_value(unsigned int index, double & r) const {get<double>(index,r);} 

,其中本專科模板get方法不針對每個子類的東西。

+0

方法真的需要虛擬嗎? –

+0

我們可以看到這個類的實現例子嗎?你如何存儲這個多態值? – Shoe

+0

該方法確實需要是虛擬的,因爲每個子類都通過多維數組和其他專門的細微差別工作。 – Luca

回答

1

你可以有一個虛擬函數調用返回一個boost::variant這樣的:

using vartype = boost::variant< 
    unsigned char, 
    char, 
    unsigned short, 
    short, 
    // ... 
>; 
virtual vartype get_value(unsigned int index) const = 0; 
+0

我錯過了什麼嗎? – Shoe

+0

1)您需要知道要讀取的類型(其大小,等等)。 2)'boost :: any'只隱藏一個變量類型,但不允許在類型之間轉換。 –

+1

@IvanGrynko,不帶'boost :: variant'。 – Shoe

4

你可能想借此看看templates。他們將允許你指定類型如下:

foo<float>(bar); // calls the float version 
foo<int>(bar); // calls the int version 
+0

你是比我快!其實我覺得這是最好的方式。 –

+0

哦,我喜歡比答案我不再要張貼。 –

+0

我太多,但我們仍然需要專門它爲每一個預期收益類型。 –

5

你應該考慮只是創建不同的功能。

int getInt(); 
double getDouble(); 

依此類推。

看來您的通話密碼必須知道在任何情況下的差異。由於您可以執行的操作沒有真正的抽象(至少顯然),所以您可以明確區分它們。模板和麪向對象的類可能會增加不必要的複雜性。

當然,爲了判斷這個,可能需要更多的上下文。只是我的0.02€:)

+0

這是爲什麼downvoted?他有一個好點,upvoting。 – OMGtechy