开发者

Implementing a default constructor

I am trying to implement a DateTime class in C++:

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, 开发者_C百科int second);
    //...

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

then in application:

DateTime date1; //default constructor

I know that having a default constructor is required for c++, but how should I implement it in this situation?

Should it set all properties to 0? That would make all other methods work, but doesn't really seem intuitive...

Should it just leave all properties un-initialized? That would make none of its methods work, but it seems more intuitive than 0, because you haven't done anything to it yet.

Should it set an internal bool initialized=false then all methods check that before operating on it?

I'm not really sure on this one. Is there a "standard" way of doing it?


Typically, the default constructor would initialize you to a "default" reference time.

If you're using a time_t internally, setting it to time_t of 0 (Unix epoch, which is 1/1/1970) would be a reasonable option, since "0" values are common defaults.

That being said, a default constructor is not required in C++ - you can have a type with no default constructor, which would require a valid "time" to be specified.


A default ctor is not required by C++. If you don't have a good idea how it should work, chances are pretty good that you just shouldn't have one. If you were going to have one, the most obvious thing to do would probably be to retrieve the current date and time.

Edit: If you don't explicitly define any ctors, then the compiler will generate a default ctor and a copy ctor for you. Neither is necessarily a particularly bad thing at all -- if you're not sure how your data should be initialized, it may be perfectly reasonable.

As far as creating a vector goes: no, you do not have to have a default ctor to put things in a vector. Normally a default ctor is used to initialize items that haven't had any value assigned to them. E.g., std::vector<DateTime> x(10); creates a vector of 10 DateTime objects, each initialized with the default ctor. If you don't have (and don't want) a default ctor, you can pass an instance of DateTime to be used to initialize those objects instead:

DateTime party_time(12, 31, 1999);
std::vector<DateTime> x(10, party_time);


If you don't want a default constructor, you can declare a private default constructor such that it can't be used.


Having a default constructor is optional, but it often makes use of your class easier in some situations. If you don't provide any constructors, then the compiler will generate a default constructor for you which is equivalent to one with an empty initializer list and an empty function body.

When implementing a default constructor, it's usually best to make it as efficient as possible as frequently of default constructor is not used or overwritten. E.g. Streaming: T t; std::cin >> t; or creating a fixed array of things to be re-assigned later T arr[100];. For this reason, while it might seem obvious to make the default constructor set a DateTime to "now", if this involves a system call or other expensive operation to find out the current date it is usually better not to do this for a default constructor.

If you had no constructors at all, then there are many situations where value-initialization would cause all your members to be initialized in any case, e.g.:

// 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();

If you supplied a default constructor but didn't explicitly initialize all the members of the class and those members were of POD-type (like time_t and int) then those members would now be left uninitialized. To get the same effect for value-initialization as if you had no user-declared constructors you would have to explicitly initialize all your members in your default constructor.

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

This would be my preferred default constructor implementation. It means that default construction is still fairly cheap, but default constucted DateTimes still have a well defined and easily recognizable value for debugging and diagnostic purposes.

While you can have an initialized boolean, allowing you to have "delayed construction", I wouldn't recommend it. It adds a lot of overhead to all the rest of the class design with what would probably be very little gain. If a client wants to manipulate DateTime with non-default values then it should be up to the client to initialize them as required.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜