Подтвердить что ты не робот

Почему мы не можем инициализировать членов класса при их объявлении?

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

class Foo
{
    int Bar = 42; // this is invalid
};

Как эквивалент использования списков инициализации конструктора.

class Foo
{
    int Bar;
public:
    Foo() : Bar(42) {}
}

Мое личное понимание заключается в том, что приведенный выше пример гораздо более выразителен и преднамерен. Более того, это более короткий синтаксис. И я не вижу никакой путаницы с другими языковыми элементами.

Есть ли официальные разъяснения по этому поводу?

4b9b3361

Ответ 1

Инициализация нестатических членов не может быть выполнена так, как это было до С++ 11. Если вы компилируете компилятор С++ 11, он должен с радостью принять код, который вы указали.

Я предполагаю, что причина не позволять ему в первую очередь состоит в том, что объявление члена данных не является определением. Объекта не вводится. Если у вас есть элемент данных, такой как int x;, объект int не создается, пока вы фактически не создадите объект типа класса. Следовательно, инициализатор этого элемента будет вводить в заблуждение. Только во время построения значение может быть присвоено члену, что и есть для списков инициализации членов.

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

struct S {
    int i(x);
    // ...
    static int x;
};

struct T {
    int i(x);
    // ...
    typedef int x;
};

Когда эти структуры разбираются во время разбора элемента i, он неоднозначен, является ли это объявлением члена данных (как в S) или объявлением функции-члена (как в T),.

С добавленной функциональностью это не проблема, потому что вы не можете инициализировать элемент с помощью этого синтаксиса скобок. Вы должны использовать логический или равный инициализатор, например:

int i = x;
int i{x};

Это могут быть только члены данных, поэтому у нас больше нет проблем.

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

Ответ 2

Основная причина заключается в том, что инициализация применяется к объекту или экземпляр, а в объявлении в классе нет объект или экземпляр; у вас этого нет, пока вы не начнете конструкционный.

В этом отношении произошла определенная эволюция. Уже на в самом конце стандартизации С++ 98, комитет добавил возможность сделать это для статических константных членов интеграла типа --- главным образом потому, что они могут использоваться в контекстах, где компилятор должен иметь возможность видеть инициализацию. В С++ 11 язык был расширен, чтобы можно было указать инициализатор в декларация, но это всего лишь стенография. инициализация по-прежнему выполняется в верхней части конструктора.

Ответ 3

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