2014-11-14 4 views
0

Что делает код:C++ разница между некоторыми конструкторами кодами

class Time { 
    private: 
     int hours; 
     int minutes; 
     int seconds; 
    public: 
     Time() { hours = 0; minutes = 0; seconds = 0; } 
}; 

отличаются от:

class Time { 
    public: 
     Time(); 

    private: 
     int hours; 
     int minutes; 
     int seconds; 
}; 

Time::Time() { 
    hours = 0; 
    minutes = 0; 
    seconds = 0;    
} 

Извините, если вопрос oversimple но я новичок в C++. Я бегу как коды и я не вижу никакой разницы ...

+4

Почему вы ожидаете разницы? – Marcin

ответ

1
class Time { 
    private: 
     int hours; 
     int minutes; 
     int seconds; 
    public: 
     Time() { hours = 0; minutes = 0; seconds = 0; } 
}; 

Этот код объявляет и определяет конструктор по умолчанию в Time класса.

class Time { 
    public: 
     Time(); 

    private: 
     int hours; 
     int minutes; 
     int seconds; 
}; 

Time::Time() { 
    hours = 0; 
    minutes = 0; 
    seconds = 0;    
} 

Этот код объявляет Time класса конструктор по умолчанию в определении класса, а затем определяет его вне определения класса. Обычно два будут разделены на Time.h и Time.cpp так:

time.h

class Time { 
    public: 
     Time(); 

    private: 
     int hours; 
     int minutes; 
     int seconds; 
}; 

Time.cpp

#include "Time.h"; 

Time::Time() { 
    hours = 0; 
    minutes = 0; 
    seconds = 0;    
} 
+1

Ваша терминология немного выключена: первая версия объявляет и определяет конструктор по умолчанию одновременно. Вторая версия объявляет ее только в определении класса, а затем определяет ее после. В C++ создаются только шаблоны. – reima

+0

Спасибо, я уточню свой ответ, терминология всегда меня отбрасывает. –

1

Функционально в отношении того, что вы видите, это не разница. Оба будут делать то же самое.

Теперь не уверен, понимаете ли вы реальную разницу, если вы новичок в программировании, но тем не менее есть разница в коде сборки, который не имеет методов более высокого уровня или неглобальных переменных ,

Первый - встроенный, что означает, что в любом месте вы делаете Time timeObj в коде сборки, вы фактически получите встроенный код. Что-то вроде того, что происходит внизу. Обратите внимание, что в вашем коде он не будет компилироваться.

Time timeObj; 
timeObj.hours = 0; 
timeObj.minutes = 0; 
timeObj.seconds = 0; 

В вашем примере это прекрасно, так как это просто. Однако в более сложных классах вы можете добавить несколько сотен строк в каждое место, где вы создаете новую версию этого объекта, что делает код намного дольше и более неэффективным.

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

Time timeObj; 
timeObj.Time(); 

Это очень простой способ объяснить это, и если это не имеет смысла, не относятся к себе с ней много еще тоже. В общем, встроенные определения хороши, если они представляют собой несколько строк простого кода, например, ваш. Но дольше, и это не должно быть реализовано как встроенная функция.

Кстати, вы можете сделать свой встроенный вариант даже лучше, выполнив следующие действия:

Time() { hours = minutes = seconds = 0; } 
+0

Это неправильно или, по крайней мере, вводит в заблуждение. Встроенные или не встроенные функции почти не имеют ничего общего с компилятором, расширяющим тело функции на сайте вызова или нет. Компилятор может свободно вызывать встроенные функции или расширять не-встроенные функции. Единственный реальный эффект встроенной функции заключается в том, что линкер должен быть уведомлен о том, что может быть несколько определений функции в разных единицах перевода. – reima

0

Если вы запустите код, они делают то же самое.

Но в 1-й версии по умолчанию ctor станет встроенной функцией, потому что она определена внутри класса.

Согласно проекту стандарта рабочего, [class.mfct] (9.3/2 в N3337)

Функция член может быть определен (8.4) в своем определении класса, в этом случае это inline member function (7.1.2), или может быть , определенным вне определения его класса, если оно уже было объявлено , но не определено в его определении класса.

1

Возможно, оффтоп, но я считаю, что это хорошая привычка делать это в списке инициализации. Для примитивных типов это не повлияет, но это будет, если у вас есть члены объекта.

Time() 
    : hours(0) 
    , minutes(0) 
    , seconds(0) {}