Рекомендация по умолчанию для членов-членов
Является ли хорошей практикой при написании кода С++ 11 для установки значений по умолчанию для членов класса в заголовочном файле класса?
Или лучше сделать это в конструкторе класса?
EDIT:
Я имею в виду:
foo.h
#include <string>
using std::string;
class Foo{
private:
string greet = "hello";
public:
Foo();
};
VS
foo.cpp (конечно же, с необходимым файлом заголовка, но без инициализации в классе):
Foo::Foo(){
greet = "hello";
}
Какой из них лучше и почему?
Ответы
Ответ 1
Если член класса всегда инициализирован с тем же начальным значением, тогда вы должны сделать инициализатор встроенным, чтобы избежать дублирования. Если начальное значение зависит от конструктора, тогда поместите его в список инициализатора конструктора. (И никогда не используйте назначение так, как вы это сделали.)
Пример:
class Foo
{
bool done = false; // always start like this
int qty;
Bar * p;
public:
Foo() : qty(0), p(nullptr) { }
Foo(int q, Bar * bp) : qty(q), p(bp) { }
explicit Foo(char const * s) : qty(std::strlen(s)), p(new Bar(s)) { }
// ...
};
В этом гипотетическом примере член done
всегда должен начинаться как false
, поэтому лучше всего писать инициализатор в строке. Остальные два члена qty
и p
могут быть инициализированы по-разному в каждом из трех разных конструкторов, поэтому они инициализируются внутри списков инициализаторов конструкторов.
Купионус: обратите внимание, что предоставление встроенного инициализатора не позволяет вашему классу иметь тривиальный конструктор по умолчанию.
Ответ 2
Это зависит от того, нужно ли вам оставаться совместимым со старыми компиляторами С++. Когда вы не используете С++ 11, вы должны инициализировать большинство членов (все нестатические) в конструкторе.
Далее многие люди выступают за явную инициализацию каждого члена, даже если это означает, что явным образом вызывается по умолчанию ctor.
Обычно вы должны размещать детали реализации в файле cpp не в файле заголовка, поэтому пример будет
Example:
//foo.h
class Foo{
public:
Foo();
private:
std::vector<int> vect;
};
//foo.cpp
Foo::Foo():vect(){
}
В С++ 11 у вас больше выбора, и в инициализаторе члена класса станет очень удобно, особенно если у вас есть несколько cors. Вот хорошая ссылка для получения дополнительной информации: http://www.stroustrup.com/C++11FAQ.html#member-init
После редактирования: В соответствии с вашим кодом вы используете С++ 11. Насколько мне известно, информации о передовых практических возможностях пока мало, но ИМХО. В инициализаторе член класса очень удобно сосредоточиться на инициализации в одном месте, что снижает сложность и типизацию
Ответ 3
Инициализация заголовков имеет основные преимущества хранения кода, более локального и понятного. Это также сохраняет некоторые типизации.
Основным недостатком, на мой взгляд, является необходимость включения большего количества заголовков для доступа к конструкторам. Простой форвардной декларации недостаточно, что делает компиляцию более длинной.