2015-02-14 6 views
0

Скорее удивлен, чтобы найти этот вопрос, не заданный раньше. На самом деле, это было задано раньше, но вопросы: ОЧЕНЬ РАЗЛИЧНЫЙ моему. Они слишком сложны и абсурдны, пока я буду держать их простыми и точными. Вот почему этот вопрос требует публикации.Как определить Struct со значениями по умолчанию?

Теперь, когда я делаю это,

struct A { 
    int a = -1; 
}; 

Я получаю следующее сообщение об ошибке: ANSI C++ forbids in-class initialization of non-const static member a

Теперь, наряду с обходным может кто-то пожалуйста, скажите мне ЛУЧШИЙ способ инициализации-структуру переменная-член со значением по умолчанию?

+3

Если вы спрашиваете о C++ перед C++ 11, то действительно ваш код не компилируется. – didierc

+2

Неужели нам нужен крик и самодовольство в этом вопросе? Просто спросите, как инициализировать структуру по умолчанию. И затем подумайте о том, чтобы продолжить существующие вопросы по теме, вместо того, чтобы размахивать ими как «абсурдные». –

+1

Вы делаете это только так, как писали. Просто обновите свой компилятор до более новой версии. – sp2danny

ответ

0

Вы можете сделать конструктор по умолчанию

struct A { 
    A() : a{-1} {} 
    int a; 
}; 
+0

Похож на обычный конструктор. Что с этим? –

+0

Он использует [список инициализации членов] (http://en.cppreference.com/w/cpp/language/initializer_list) вместо инициализации в теле конструктора. Это [предпочтительно вообще] (https://stackoverflow.com/questions/4589237/in-this-specific-case-is-there-a-difference-between-using-a-member-initializer), особенно если переменные-члены являются классами. – CoryKramer

+0

Хммм ... Мне жаль, что везде не было стандартного соглашения. –

3

Во-первых, давайте посмотрим на ошибку:

ANSI C++ forbids in-class initialization of non-const static member a 

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

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

Обычно люди пишут инициализации члена в конструкторе, как это:

struct SomeType 
{ 
    int i; 
    SomeType() 
    { 
     i = 1; 
    } 
} 

Но это на самом деле не инициализации, но назначение. Когда вы войдете в тело конструктора, то, что вы сделали, - это элементы, инициализируемые по умолчанию. В случае фундаментального типа, такого как int, «инициализация по умолчанию» в основном сводится к «eh, просто используйте любое значение в тех байтах, которые я вам дал.«

Что будет дальше, так это то, что вы спрашиваете i теперь принять значение 1 через оператор присваивания. Для такого тривиального класса эта разница незаметна. Но когда у вас есть члены const (которые к тому времени они не могут быть перехвачены с новым значением) и более сложные члены, которые не могут быть инициализированы по умолчанию (поскольку они не предоставляют доступный видимый конструктор с нулевыми параметрами) , вы скоро обнаружите, что код не может быть скомпилирован.

Правильный путь:

struct SomeType 
{ 
    int i; 
    SomeType() : i(1) 
    { 
    } 
} 

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

Иногда вы можете видеть членов, инициализированных фигурными скобками (что-то вроде i{1}, а не i(c)). Различия могут быть незначительными, в большинстве случаев это одно и то же, и текущие версии Стандарта пытаются сгладить некоторые морщины. Но это все выходит за рамки этого вопроса.

Обновление: Имейте в виду, что то, что вы пытаетесь написать, теперь является действительным кодом на C++ и с момента ратификации C++ 11. Эта функция называется «инициализаторы нестатических данных», и я подозреваю, что вы используете некоторую версию Visual Studio, которая по-прежнему поддерживает поддержку как «частичную» для этой конкретной функции. Подумайте об этом как о короткой форме синтаксиса инициализации элемента, который я описал ранее, автоматически вставляемого в любой конструктор, который вы объявляете для этого конкретного типа.

+1

'i {1}' был добавлен в C++ 11 –

+0

Правда, я почти написал {} там, лично я нахожусь в области автоининга и скобки-инициализации всего, но я чувствовал, что будет мутить ответ. – ZaldronGG

+1

Вы должны объяснить, что код OP действителен C++. У них просто нет компилятора, который поддерживает новейшие стандарты. – juanchopanza

Смежные вопросы