Вопрос по constructor, c++11, header-files, c++, default-value – Член по умолчанию ценит лучшие практики

56

Это хорошая практика при написании кода C ++ 11, чтобы установить значения по умолчанию для членов класса в заголовочном файле класса?

Или лучше сделать это в конструкторе класса?

РЕДАКТИРОВАТЬ:

Я имею в виду:

foo.h:

#include <string>

using std::string;

class Foo{
    private:
        string greet = "hello";
    public:
        Foo();
};

В.С.

foo.cpp (конечно, с необходимым заголовочным файлом, но без инициализации в классе):

Foo::Foo(){
    greet = "hello";
}

Какой из них лучше и почему?

Что вы имеете в виду в заголовочном файле? C ++ 11 в классе инициализации члена? Пример кода обоих случаев поможет проиллюстрировать это. chris
следует избегать использования пунктов в заголовке vlad_tepesch
@chris обновлен примерами кода. Paul
Эти два образца делают разные вещи, поэтому, конечно, первый лучше. Ищиmember initialization list K-ballo

Ваш Ответ

3   ответа
11

Это зависит от того, нужно ли вам оставаться совместимым со старыми компиляторами C ++. Когда вы не используете C ++ 11, вам нужно инициализировать большинство членов (все нестатические) в конструкторе. Кроме того, многие люди выступают за явную инициализацию каждого члена, даже если это означает явный вызов ctor по умолчанию. Обычно вы должны поместить детали реализации в файл cpp, а не в файл заголовка, таким образом, пример будет

Example:
//foo.h

class Foo{
public: 
  Foo();
private:
  std::vector<int> vect;
};

//foo.cpp

Foo::Foo():vect(){
}

В C ++ 11 у вас есть более широкий выбор, и инициализация в классе станет очень удобной, особенно если у вас есть несколько cors. Вот хорошая ссылка для получения дополнительной информации:http://www.stroustrup.com/C++11FAQ.html#member-init

After Edit: Согласно вашему коду вы используете C ++ 11. Насколько мне известно, информации о передовой практике относительно новых возможностей очень мало, но IMHO В инициализаторе членов класса очень удобно сконцентрировать инициализацию в одном месте, что уменьшает сложность и типизацию

Да, я обновил свой вопрос, чтобы лучше отразить то, что имел в виду. Я в основном согласен с вами в том, что "уменьшает сложность и ввод текста". Paul
71

Если член класса всегда инициализируется одним и тем же начальным значением, то вы должны сделать инициализатор встроенным, чтобы избежать дублирования. Если начальное значение зависит от конструктора, поместите его в список инициализатора конструктора. (И никогда не используйте назначение так, как вы.)

Пример:

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, может инициализироваться по-разному в каждом из трех различных конструкторов, поэтому они инициализируются внутри конструкторов & apos; списки инициализаторов.

A curiosum: Note that providing an inline initializer prevents your class from having a trivial default constructor.

@ JohannesSchaub-litb: Это очень верно, хотя я думаю, что эта функция решает несколько ортогональную проблему.
@ cp.engr: потому что вы обычно должны инициализировать, а не переназначать.
& quot; никогда не используйте назначение так, как вы. & quot; Я думаю, что объяснение, почему никогда не следует делать это, было бы хорошим дополнением к вашему ответу.
@KerrekSB В чем разница между назначением, которое использовал Пол, и назначением, которое вы использовали? Оба присваивают значение переменной-члена.
Вы также можете использовать делегирование конструктора, чтобы избежать избыточности.
2

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

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

Похожие вопросы