Инициализация членов класса - значения по умолчанию или member-init-list? - PullRequest
2 голосов
/ 21 апреля 2019

Я немного запутался, когда и как инициализировать члены класса в конструкторе.Если я все правильно понимаю, вы можете сделать это, включив значения по умолчанию в определение класса, список инициализатора члена конструктора или присваивая его в теле конструктора.Я понимаю, что лучше всего выполнить инициализацию перед вводом тела конструктора, но когда вам следует использовать список инициализаторов членов и когда следует использовать значения по умолчанию?

Извинения, если я что-то здесь неправильно понял.

1 Ответ

1 голос
/ 08 мая 2019

Вы действительно немного сбиваете с толку. Существует как минимум 4 разных понятия

вы сделали 3.

В следующих примерах ( на ideone.com ) Я использую struct вместо class и встроенные конструкторы для краткости / явно.

#include <iostream>

struct A 
{ 
    A(int v=1): m(v) {}
    int m; 
};

struct B
{ 
    B(): m(2) {}
    int m; 
};

struct C
{ 
    C()
    {
        m = 3;
    }
    int m; 
};

// since C++11
struct D
{ 
    int m = 11; 
};

int main()
{
    using namespace std;
    #define TRACE(arg) cout << #arg ": " << arg.m << endl; 
    A a1;
    TRACE(a1)
    A a2(4); 
    TRACE(a2)
    B b;
    TRACE(b)
    b.m = 5;
    TRACE(b)
    C c;
    TRACE(c)
    c.m = 6;
    TRACE(c)
    D d;
    TRACE(d)
    d.m = 0;
    TRACE(d)
    #undef TRACE
}

Использование A отличается от B, C и D.

Только A обеспечивает способ инициализации m значением, отличным от значения по умолчанию. Все варианты предоставляют прямой доступ к m (в большинстве случаев это плохой выбор, рассматривайте его как заполнитель для более изощренного способа изменения члена) Вы должны изменить объект, если нет доступа к фактическим значениям инициализатора. Это делает m для постоянной объектов B, C и D эффективной константой времени компиляции. Следует избегать «инициализации» элемента в теле конструктора (C), если можно использовать список инициализаторов (A или B) (иногда это не так тривиально, как показано здесь).

Опция D должна быть оценена, если вы используете C ++ 11 или более позднюю версию.

Так что A кажется наиболее гибким вариантом. Но это не очень хорошая модель для инициализации двух или более членов: слишком легко перепутать порядок параметров.


[1] эта опция была добавлена ​​после того, как я (благодаря NikosC ) понял, что эти опции существуют

...