2015-03-31 49 views
0

我有一个基类Attr(属性),它有两个派生类NomAttr(Nominal属性)和NumAttr(数值属性)。如何设计具有不同返回类型的基类和派生类?

每个都有一个name成员,它总是字符串类型。

然而,他们的value成员不同:对于NomAttr,我想它的valuestring类型,但对于NumAttr,我想它的valuedouble类型。

虚拟函数不允许不同的返回类型,所以我有点卡在这里。 (起初,我得出以下UML到我的意图模型。)

UML


很多人问我,以显示真正的问题。以下是全球视图:

这是机器学习者。 Attr是数据集中实例的一部分:
A DataSetIns(实例)列表组成。
InsAttr s的列表组成,Attr的计数和每个Attr的类型在运行时是已知的,从用户使用命令行参数提供的数据文件解析。
在这里你去:
enter image description here

+1

您可以使用模板。 – 2015-03-31 15:12:10

+0

我建议返回提升任何或增强变体。 – imreal 2015-03-31 15:13:24

+1

你能展示你正在尝试解决的真正问题和使用'Attr'的上下文吗? C++是强类型的,并不直接支持你想要做的事情,但根据REAL的需要,可以使用各种机制(可能是静态或动态多态)。 – 2015-03-31 15:14:36

回答

2

所以根据您的更新,我不认为你需要任何继承在所有处理您的ATTR。相反,基数Attr直接包含该值作为boost::variant<double, std::string>,并且由于您知道它将是什么类型,因此只需从每个属性的变体中获取正确的类型即可。

+0

谢谢。我需要尝试一下。 – modeller 2015-03-31 16:07:59

-1

要么使用模板像其他用户建议或代替返回值传递给引用设置的值。

的伪代码EX:

//this code has your problem 
virtual int func(); 

int func(int a) override 
{return a + 3}; 
int a = func(3);//a will be 6 

//this code does not 
virtual void procedure(); 

void procedure(int a, int* b) override 
{*b=a+3}; 
int a; 
func(3,&a);//a will be 6 
2

使用模板:

#include <iostream> 
#include <string> 

template <typename T> class Attribute{ 
public: 
    Attribute() : mAttr(T()) { } 
    Attribute(T pAttr) : mAttr(pAttr) { } 
    T getAttr() { return mAttr; } 
private: 
    T mAttr; 
}; 

class NumAttr : public Attribute<int>{ 
public: 
    NumAttr() : Attribute<int>(0) { } 
    NumAttr(int pAttr) : Attribute<int>(pAttr) { } 
}; 

class NomAttr : public Attribute<std::string>{ 
public: 
    NomAttr() : Attribute<std::string>(std::string()) { } 
    NomAttr(std::string pAttr) : Attribute<std::string>(pAttr) { } 
}; 
int main(void){ 
    NomAttr name(std::string("test")); 
    NumAttr number(1); 
    std::cout << "Name: " << name.getAttr() << std::endl; 
    std::cout << "Number: " << number.getAttr() << std::endl; 
} 

注意,其实没有必要对派生类,你可以只使用Attribute<int>Attribute<std::string>或任何其他类型的需要。

编辑:如果类型在编译时不知道,这将不起作用,请参阅@MarkB答案。

0

其实你只需要一个template derived class

#include <iostream> 
#include <string> 
using namespace std; 

template <typename T> 
class Base 
{ 
public: 
    virtual T getValue() = 0; 
protected: 
    T value; 
}; 

template<typename T> 
class Derived : public Base<T> 
{ 
public: 
    Derived(T v) 
    { 
     value = v; 
    } 
    T getValue() 
    { 
     return value; 
    } 
}; 

int main() 
{ 
    Derived<string> d1 = Derived<string>("test"); 
    Derived<double> d2 = Derived<double>(3.14); 

    cout << d1.getValue() << endl; 
    cout << d2.getValue() << endl; 

    return 0; 
} 
相关问题