2014-03-06 63 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