4

我正在尝试在 C++ 中实现一个 DateTime 类:

class DateTime {
public:
    DateTime();
    DateTime(time_t ticks);
    DateTime(int day, int month, int year);
    DateTime(int day, int month, int year, int hour, int minute, int second);
    //...

private:
    time_t ticks;
    int day;
    int month;
    //...
}

然后在应用程序中:

DateTime date1; //default constructor

我知道 C++ 需要有一个默认构造函数,但是在这种情况下我应该如何实现它呢?

是否应该将所有属性设置为 0?这将使所有其他方法都有效,但看起来并不直观......

它应该让所有属性都未初始化吗?这将使它的任何方法都不起作用,但它似乎比 0 更直观,因为你还没有对它做任何事情。

它是否应该设置一个内部bool initialized=false然后所有方法在对其进行操作之前检查它?

我不太确定这一点。有没有“标准”的做法?

4

4 回答 4

9

通常,默认构造函数会将您初始化为“默认”参考时间。

如果您在time_t内部使用 a,将其设置time_t为 0(Unix epoch,即 1970 年 1 月 1 日)将是一个合理的选择,因为“0”值是常见的默认值。

话虽这么说,C++ 中不需要默认构造函数——你可以有一个没有默认构造函数的类型,这需要指定一个有效的“时间”。

于 2009-11-06T21:45:37.120 回答
8

C++不需要默认 ctor 。如果您不知道它应该如何工作,那么您很可能不应该拥有它。如果您要拥有一个,最明显的做法可能是检索当前日期和时间。

编辑:如果您没有明确定义任何 ctor,那么编译器将为您生成一个默认 ctor 和一个复制 ctor。两者都不一定是一件特别糟糕的事情——如果你不确定你的数据应该如何初始化,这可能是完全合理的。

就创建向量而言:不,您不必拥有默认 ctor 即可将事物放入向量中。通常,默认 ctor 用于初始化尚未分配任何值的项目。例如,std::vector<DateTime> x(10);创建一个包含 10 个DateTime对象的向量,每个对象都使用默认 ctor 进行初始化。如果您没有(也不想要)默认 ctor,则可以传递一个DateTime用于初始化这些对象的实例:

DateTime party_time(12, 31, 1999);
std::vector<DateTime> x(10, party_time);
于 2009-11-06T21:46:19.120 回答
1

如果您不想要默认构造函数,则可以声明一个私有默认构造函数,使其无法使用。

于 2009-11-06T21:49:28.297 回答
1

拥有默认构造函数是可选的,但在某些情况下,它通常可以更轻松地使用您的类。如果您不提供任何构造函数,那么编译器将为您生成一个默认构造函数,该构造函数等效于具有空初始值设定项列表和空函数体的构造函数。

在实现默认构造函数时,通常最好使其尽可能高效,因为不使用或覆盖默认构造函数。例如流式传输:T t; std::cin >> t;或创建一个固定的事物数组,以便稍后重新分配T arr[100];。出于这个原因,虽然将默认构造函数设置为“现在”似乎很明显DateTime,但如果这涉及系统调用或其他昂贵的操作来找出当前日期,通常最好不要对默认构造函数执行此操作。

如果您根本没有构造函数,那么在许多情况下,值初始化会导致您的所有成员在任何情况下都被初始化,例如:

// Explicit value-initialzation of dynamcially allocated DateTime
DateTime* pdt = new DateTime();

// Value-initialized temporary
FunctionTakesDateTime( DateTime() );

// Copy-initalization from a value-initialized temporary
DateTime dt = DateTime();

如果您提供了默认构造函数但没有显式初始化类的所有成员并且这些成员是 POD 类型的(如time_tint),那么这些成员现在将保持未初始化状态。要获得与没有用户声明的构造函数一样的值初始化效果,您必须在默认构造函数中显式初始化所有成员。

DateTime() : ticks(), days(), months() /*, ... */ {}

这将是我首选的默认构造函数实现。这意味着默认构造仍然相当便宜,但默认构造DateTime的 s 仍然具有良好定义且易于识别的值,用于调试和诊断目的。

虽然你可以有一个initialized布尔值,让你有“延迟构造”,但我不推荐它。它为所有其他类设计增加了很多开销,而收益可能很小。如果客户端想要DateTime使用非默认值进行操作,则应由客户端根据需要对其进行初始化。

于 2009-11-06T23:07:06.777 回答