如何设计具有不同返回类型的基类和派生类?

时间:2015-03-31 15:08:51

标签: c++ uml virtual

我有一个基类Attr(属性),它有两个派生类NomAttr(标称属性)和NumAttr(数字属性)。

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

但是,他们的value成员有所不同:对于NomAttr,我想获得其value string类型,但对于NumAttr,我想要得到value double类型的Attr

虚函数不允许不同的返回类型,所以我有点卡在这里。 (最初我绘制下面的UML来模拟我的意图。)

UML


很多人要我展示真正的问题。这是一个全球视图:

这是一名机器学习者。 DataSet是数据集中实例的一部分:
InsIns(实例)列表组成 AttrAttr列表组成,Attr的计数和每个{{1}}的类型在运行时是已知的,从用户提供的数据文件中解析用命令行参数。
你走了:
enter image description here

4 个答案:

答案 0 :(得分: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答案。

答案 1 :(得分:2)

因此,根据您的更新,我认为您根本不需要任何继承来处理您的attr。相反,让基础Attr直接包含值boost::variant<double, std::string>,并且因为您知道它将是什么类型,您可以简单地从每个属性的变体中获取正确的类型。

答案 2 :(得分: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;
}

答案 3 :(得分:-1)

使用像其他用户建议的模板,或者不是返回值,而是传递要通过引用设置的值。

Psuedo Code 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