针对稍微相关的对象的C++类设计

C++ class design for slightly related objects

本文关键字:对象 C++      更新时间:2023-10-16

我正在编写一个应用程序,它的"任务"(实际上是假期中的步骤)具有一定程度(最小)的重叠。标准任务或多或少是这样设计的(修剪私人成员):

#include <QMetaType>
#include <QString>
#include <QDateTime>
#include <QVector>
namespace Marble
{
class GeoDataPlacemark;
}
namespace HolidayPlanner
{
class HolidayTask: public QObject
{
Q_OBJECT
public:
explicit HolidayTask(QString name, ActivityType type=Lodging, QObject* parent=0);
virtual ~HolidayTask();
QString name() const;
QString description() const;
Marble::GeoDataPlacemark *location() const;
virtual ActivityType type() const;
const QDateTime startDate() const;
const QDateTime endDate() const;
void setName(const QString &name);
void setDescription(const QString &description);
void setStartDate(const QDateTime &dateTime);
void setStartDate(int year, int month, int day, int hour, int minutes);
void setEndDate(const QDateTime &dateTime);
void setEndDate(int year, int month, int day, int hour, int minutes);
void setLocation(Marble::GeoDataPlacemark *location);
// private members, etc... 
};
} // namespace HolidayPlanner

现在的问题是如何定义任务,例如单个类或其他类继承的基类。更清楚地说:

  • 任务通常有名称和描述
  • 它们都有开始日期,有些是结束日期
  • 有些只有一个位置(例如一个城市),另一些有两个位置(如从和到)
  • type()函数返回任务的"类型"(枚举中的标志)
  • 根据任务的不同,应用程序需要略微不同地处理数据(即,如果使用单个位置任务,则不要显示"from"answers"to"窗口小部件,等等)

我最初用一个类+一个派生类来处理"从位置"answers"到位置的情况",但我不确定它是否太干净。另一方面,我不确定只使用通用方法(name()和description(),也许startDate()和endDate())创建基类是否有意义。

考虑到上述用例,什么是最佳的操作方案?

我不同意组合比继承更好的观点。如果被迫的话,可以不总是使用作文吗?是的,但这可能不是最好的。。。。例如虚拟函数、基本对象类型的容器。

我更喜欢IS-A和HAS-A测试来确定要做什么。

  • 任务通常有一个名称和一个描述-如果这些是派生对象的常量,则在基中是纯虚拟函数(也称为接口)。否则就只是成员
  • 所有这些都有开始日期,其中一些是结束日期-开始-->基础,结束-->派生
  • 一些有一个位置(例如一个城市),另一些有两个位置(如从和到)-一个位置矢量(三条腿,四条腿?)
  • type()函数返回任务的"类型"(枚举中的标志)-使其成为基中的纯虚拟函数(也称为接口)
  • 根据任务的不同,应用程序需要稍微不同地处理数据(即,如果使用单个位置任务,则不要显示"from"answers"to"窗口小部件等)-阅读有关模型/视图/控制器(MVC)的信息

如果可能的话,使用组合而不是继承总是更好的。但是,如果每种类型的任务都有许多相同的项,那么你可以很容易地有一个基类,然后从中派生,并为上面提到的其他位置有一个重载函数,然后派生类可以有自己的方法来对该任务进行个人操作。