相同的函数,类层次结构的不同返回类型
我们有一个看起来像这样的类层次结构:
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);
}
};
它可以很好地完成其工作,但这意味着我必须在每个类中定义每个成员函数。 例如,如果我想要一个名为 getValue 的函数,我将需要另外很多这样的模板函数。
类成员的数据类型在类定义时就已知,因此必须再次将它们放入函数定义中似乎是重复。 有没有可能的方法来避免函数定义中的所有模板业务?
谢谢。
安迪
PS 我看到了以下问题,但该问题中的问题略有不同: 根据数据返回不同的数据类型(C++)
We have a class hierarchy which looks something like this:
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();
};
Now we need to write a function which computes the value by multiplying the price and quantity. The aim is to make it as simple as possible to add new classes in the future. As you may be aware, this is not straightforward because the data types of these fields are different for different classes. In effect, we have these functions to do the same thing conceptually, but in programming terms they are different operations.
To minimise the amount of cut and paste required, the solution I can think of so far is to use template functions:
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);
}
};
It does its job all right, but this will mean that I have to define every single member function in each class. For example, I will need another lot of these template functions if I want to have a function called getValue, say.
The data types of the class members are known when the class is defined, so having to put them in the function definitions again seem to be a duplication. Is there a possible way to avoid all this template business in the function definitions?
Thank you.
Andy
PS I have seen the following question, but the issue in that question is slightly different:
Returning different data type depending on the data (C++)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
虽然我不能说我喜欢拥有多个派生类以及返回不同类型的函数的想法,但有一种方法可以做到这一点。
这使您可以改变派生类中的 value_type,但在基类中声明所有常用函数(就像您应该做的那样)。 这类似于 STL 中用于地图等的方法。
While I can't say I like the idea of having multiple derived classes with a function that returns different types, there is a way to do this.
This lets you vary the value_type in the derived class, but declare all your common functions in the base (like you ought to do). This is similar to the approach used in the STL for maps and such.
使用奇怪的重复模板模式 (CRTP):
请注意,我必须将
m_price
和m_quantity
设为公共,以便基类可以访问它们。 您可能不想这样做,因此您需要添加公共访问器(或使用已经存在的访问器,如果有的话),或者使它们成为基类的受保护成员(由 typedef 指定的类型)在派生类中),或者让派生类将基类声明为友元。如果您想要一个公共的
getValue
成员函数,您可以将其添加到基类中并将继承设置为公共。Use the Curiously Recurring Template Pattern (CRTP):
Note that I've had to make
m_price
andm_quantity
public in order that the base class can access them. You probably don't want to do that, so instead you will need either to add public accessors (or use the ones which are there already, if any), or else make them protected members of the base class (of types specified by typedefs in the derived class), or else have the derived class declare the base class a friend.If you want a public
getValue
member function, you can add it to the base class and make the inheritance public.OO 解决方案是创建一个返回类型的类。 然后,您可以将此返回类型子类化为专用返回类型。
无论如何,使用浮点数学来赚钱会给你带来麻烦。
The OO solution would be to create a class of the return type. You can then subclass this return type for specialized return types.
In any case, using floating point math for money will get you in trouble.
这样的事情会做吗?
Would something like this do?
你可以这样做:
You could do: