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

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

пример:

struct s {
   int i = 10;
};

Потому что это определение, а не декларация

Archmede 02.05.2017 02:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
54
1
69 789
6

Ответы 6

Если вы хотите инициализировать элементы нестатический в structдекларация:

В C++ (не C) structs почти синонимичны классам и могут иметь элементы, инициализированные в конструкторе.

struct s {
    int i;

    s(): i(10)
    {
    }
};

Если вы хотите инициализировать пример:

В C или C++:

struct s {
    int i;
};

...

struct s s_instance = { 10 };

C99 также имеет функцию, называемую назначенными инициализаторами:

struct s {
    int i;
};

...

struct s s_instance = {
    .i = 10,
};

Существует также расширение GNU C, которое очень похоже на назначенные инициализаторы C99, но лучше использовать что-то более переносимое:

struct s s_instance = {
    i: 10,
};

Не могли бы вы уточнить свой последний пример?

phougatv 03.02.2016 07:01

Edit2: Этот ответ был написан в 2008 году и относится к C++ 98. Правила инициализации членов были изменены в последующих версиях языка.

Редактировать: Первоначально вопрос был помечен как c++, но на плакате говорилось, что он касается c, поэтому я повторно пометил вопрос, но оставляю ответ ...

В C++ struct - это просто class, который по умолчанию используется для public, а не для private для членов и наследования.

C++ позволяет инициализировать только неотъемлемые члены static const в строке, другие члены должны быть инициализированы в конструкторе, или если struct является POD в списке инициализации (при объявлении переменной).

struct bad {
    static int answer = 42; // Error! not const
    const char* question = "what is life?"; // Error! not const or integral
};

struct good {
    static const int answer = 42; // OK
    const char* question;
    good() 
        : question("what is life?") // initialization list
        { }
};

struct pod { // plain old data
    int answer;
    const char* question;
};
pod p = { 42, "what is life?" };

Это уже давно устарело ... Теперь это позволяет C++!

sergiol 15.05.2020 01:16

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

struct s { int i=10; };

Здесь не объявляется никакая переменная - он определяет тип. Чтобы объявить переменную, вы должны добавить имя между } и ;, а затем инициализировать его после этого:

struct s { int i; } t = { 10 };

Как отметили Checkers, в C99 вы также можете использовать назначенные инициализаторы (что является прекрасным улучшением - однажды C догонит другие функции, которые имел Fortran 66 для инициализации данных, в первую очередь повторяя инициализаторы определенное количество раз). Эта простая структура не дает никаких преимуществ. Если у вас есть структура, скажем, с 20 членами и вам нужно только инициализировать один из них (скажем, потому что у вас есть флаг, который указывает, что остальная часть структуры инициализирована или нет), это более полезно:

struct s { int i; } t = { .i = 10 };

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

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

int a = 10;
  • если это авто, то чем в стековой памяти будет выделено
  • если он глобальный, чем в разделах данных, которые будет выделяться памятью

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

Хотя ваш ответ кажется приятным, вы должны попытаться сделать его более ясным, например, исправив свои формулировки!

gsamaras 14.03.2016 21:20

Обратите внимание, что в C++ 11 теперь разрешено следующее объявление:

struct s {
   int i = 10;
};

Это старый вопрос, но он занимает высокое место в Google и с тем же успехом может быть прояснен.

Что именно он делает? Сравнимо ли это со значением инициализации конструктора по умолчанию? Если да: будет ли это присвоение выполняться, если вызывается конструктор копирования или перемещения?

starturtle 01.08.2016 17:35

Он в основном вставляется в список инициализации членов ваших конструкторов, если член не инициализирован явно.

Trass3r 18.09.2017 17:25

Это где-нибудь задокументировано?

Andrew Truckle 02.07.2018 21:01

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

Другие вопросы по теме