C++ 相同的函数,不同的类层次结构返回类型

C++ 相同的函数,不同的类层次结构返回类型,c++,function,templates,overriding,C++,Function,Templates,Overriding,我们的类层次结构如下所示: class base { }; class derived1 : protected base { private: float m_price; int m_quantity; float m_value; public: // float calculateValue(); }; class derived2 : protected base { private: double m_price; long m_quan

我们的类层次结构如下所示:

class base
{
};

class derived1 : protected base
{
private:
    float m_price;
    int m_quantity;
    float m_value;
public:
//  float calculateValue();
};

class derived2 : protected base
{
private:
    double m_price;
    long m_quantity;
    double m_value;
public:
//  double calculateValue();
};
现在我们需要编写一个函数,通过乘以价格和数量来计算价值。目的是使将来添加新类尽可能简单。您可能知道,这并不简单,因为这些字段的数据类型对于不同的类是不同的。实际上,我们有这些函数在概念上做同样的事情,但在编程术语中,它们是不同的操作

为了最大限度地减少所需的剪切和粘贴量,到目前为止,我能想到的解决方案是使用模板功能:

template <class A, B, C>
A calculate_value(B price, C quantity)
{
    A result;
    // Some code to do the multiplication, not sure if template specialisation is needed
    return result;
};

class derived1 : protected base
{
private:
    float m_price;
    int m_quantity;
    float m_value;
public:
    float calculateValue()
    {
       calculate_value < float, float, int > (m_price, m_quantity);
    }
};
模板
A计算_值(B价格,C数量)
{
结果,;
//一些代码用于执行乘法,不确定是否需要模板专门化
返回结果;
};
类derived1:受保护的基
{
私人:
浮动市价;
国际货币单位数量;
浮动m_值;
公众:
浮点计算值()
{
计算单位价值(单位价格,单位数量);
}
};
它的工作做得很好,但这意味着我必须定义每个类中的每个成员函数。例如,如果我想有一个名为getValue的函数,比如说,我需要另外很多这样的模板函数

在定义类时,类成员的数据类型是已知的,因此必须再次将它们放入函数定义中似乎是重复的。是否有可能避免函数定义中的所有模板业务

多谢各位

安迪

PS我看到了以下问题,但该问题中的问题略有不同:
面向对象的解决方案是创建一个返回类型的类。然后可以将此返回类型子类化为专用返回类型

在任何情况下,使用浮点数学赚钱都会给你带来麻烦。

虽然我不能说我喜欢使用多个派生类和返回不同类型的函数的想法,但有一种方法可以做到这一点

template
class base<typename value_type>
{
public:
    value_type calculateValue();
};
class derived1 : protected base<float>
{
private:
    float m_price;
    int m_quantity;
    float m_value;
};
class derived2 : protected base<double>
{
private:
    double m_price;
    long m_quantity;
    double m_value;
};
模板
阶级基础
{
公众:
值类型calculateValue();
};
类derived1:受保护的基
{
私人:
浮动市价;
国际货币单位数量;
浮动m_值;
};
类derived2:受保护的基
{
私人:
双m_价格;
长m_数量;
双m_值;
};

这允许您改变派生类中的值类型,但在基类中声明所有公共函数(就像您应该做的那样)。这类似于STL中用于地图等的方法。

这样做可以吗

template <typename A,typename B,typename C>
class base{
protected:
    A m_price;
    B m_quantity;
    C m_value;
public:
    C calculateValue(){
        m_value = m_quantity * m_price;
        return m_value;
    }
};

class derived1 : public base<int,float,int>{
};

class derived2 : public base<long,double,long>{
};
模板
阶级基础{
受保护的:
m_价格;
B m_数量;
C m_值;
公众:
C calculateValue(){
m_值=m_数量*m_价格;
返回m_值;
}
};
类derived1:公共基{
};
派生类2:公共基{
};

使用奇怪的重复模板模式(CRTP):

模板
阶级基础{
受保护的:
typename派生::值\类型calculateValue(){
派生*self=静态_转换(此);
退货自->毛坯价格*自->毛坯数量;
}
};
类derived1:受保护的基{
公众:
类型定义浮点值\u类型;
浮动市价;
国际货币单位数量;
};
类derived2:受保护的基{
公众:
typedef双值_类型;
双m_价格;
长m_数量;
};
请注意,我必须将
m_price
m_quantity
公开,以便基类可以访问它们。您可能不想这样做,因此您需要添加公共访问器(或者使用已经存在的访问器,如果有的话),或者使它们成为基类的受保护成员(由派生类中的typedefs指定的类型),或者让派生类将基类声明为友元

如果您想要一个public
getValue
成员函数,可以将其添加到基类中,并将继承公开。

您可以执行以下操作:

template class base { public: void calculateValue(value_type& x); }; class derived1 : protected base { private: float m_price; int m_quantity; float m_value; }; class derived2 : protected base { private: double m_price; long m_quantity; double m_value; }; 模板 阶级基础 { 公众: 无效计算值(值类型和x); }; 类derived1:受保护的基 { 私人: 浮动市价; 国际货币单位数量; 浮动m_值; }; 类derived2:受保护的基 { 私人: 双m_价格; 长m_数量; 双m_值; };
我同意使用浮点数学进行重复乘法/除法不是一个好主意。这只是一个示例。事后看来,我本可以选择另一种手术。 template class base { public: void calculateValue(value_type& x); }; class derived1 : protected base { private: float m_price; int m_quantity; float m_value; }; class derived2 : protected base { private: double m_price; long m_quantity; double m_value; };