2009-11-06 5 views
4

Я пытаюсь реализовать класс DateTime в 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, int second); 
    //... 

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

затем в применении:

DateTime date1; //default constructor 

Я знаю, что наличие конструктора по умолчанию требуется для C++, но как следует ли его реализовать в этой ситуации?

Должно ли оно задавать все свойства 0? Это заставит все другие методы работать, но на самом деле не кажется интуитивным ...

Должно ли оно просто оставить все свойства неинициализированными? Это не сделало бы ни один из его методов, но кажется более интуитивным, чем 0, потому что вы еще ничего не сделали для этого.

Должен ли он установить внутренний bool initialized=false, тогда все методы проверяют, что перед его работой?

Я не уверен в этом. Есть ли «стандартный» способ сделать это?

ответ

9

Как правило, конструктор по умолчанию инициализирует вас стандартным опорным временем.

Если вы используете time_t внутренне, установив его на time_t 0 (Unix epoch, который 1.1.1970) было бы разумным вариантом, так как «0» значения являются общими по умолчанию.

При этом конструктор по умолчанию не требуется в C++ - у вас может быть тип без конструктора по умолчанию, для которого требуется указать действительное «время».

8

По умолчанию ctor не, требуемый C++. Если у вас нет хорошей идеи, как это должно работать, шансы довольно хорошие, что вы просто не должны их иметь. Если бы у вас его было, наиболее очевидной задачей, вероятно, было бы получить текущую дату и время.

Редактировать: Если вы не указали явное определение каких-либо ctors, компилятор будет генерировать по умолчанию 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); 
+0

Ну, как я понимаю, если я не укажу по умолчанию, компилятор создает для меня один, который, как я понимаю, в основном плохой. –

+0

В некоторых случаях требуется конструктор по умолчанию. Например, если вы хотите иметь вектор объектов DateTime. –

+0

Или это, только если нет других объявленных конструкторов, по умолчанию или нет? –

1

Если вы не хотите, конструктор по умолчанию, вы можете объявить частный конструктор по умолчанию, чтобы его нельзя было использовать.

+2

Кроме того, если вы определяете какие-либо конструкторы, компилятор не генерирует значение по умолчанию. Поэтому это полезно, если вы не хотите конструкторов. Я не могу представить, почему вы хотели бы это сделать. Однако этот метод полезен, когда конструкторы копирования и операторы присваивания копий вынуждают объект не копироваться. –

+0

@Fred Larson: Создание закрытого конструктора - это основная техника, используемая для создания синглтонов и статических методов фабрики. – Lalaland

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_t и int), тогда эти члены теперь останутся неинициализированными. Чтобы получить такой же эффект для инициализации значения, как если бы у вас не было объявленных пользователем конструкторов, вам нужно было бы явно инициализировать все ваши члены в вашем конструкторе по умолчанию.

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

Это была бы моя предпочтительная реализация конструктора по умолчанию. Это означает, что построение по умолчанию по-прежнему довольно дешево, но по умолчанию const 0ed DateTime s все еще имеют четко определенное и легко узнаваемое значение для целей отладки и диагностики.

В то время как у вас может быть значение initialized boolean, позволяющее иметь «отложенную конструкцию», я бы не рекомендовал его. Это добавляет много накладных расходов для всего остального класса дизайна с тем, что, вероятно, будет очень мало выгоды. Если клиент хочет манипулировать DateTime с нестандартными значениями, то он должен быть до клиента, чтобы инициализировать их по мере необходимости.

Смежные вопросы