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

Это общий вопрос программирования. Я изучаю С++, и я узнал, что любые константные переменные, т.е.: const int i или int *const ptr, должны быть инициализированы сразу.

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

Но я не могу найти причину, почему это должно быть сделано/почему это правило наложено.

Кто-нибудь может объяснить это мне?

Ответ 1

Потому что вы не можете его инициализировать или назначить со значением позже.

const int size; //no initialization (error)

size = 100; //error - you cannot assign a const variable.

Теперь, если переменная, которая не имеет какого-либо значимого значения, и вы не можете заставить ее иметь значение позже, потому что это переменная const, то в чем же смысл такой переменной? Это совершенно бесполезно.

Однако это справедливо только для встроенных и POD-типов:

struct A{}; //POD type
struct B{ B(){} }; //Non POD type because it has user-defined constructor!

const int i; //error - built-in type
const A a;   //error - POD type
const B b;   //ok -    Non POD type

//likewise
const std::string s; //ok - std::string is a non-POD
const std::vector<std::string> v; //ok - std::vector is a non-POD

На самом деле тип NON-POD не может оставаться неинициализированным, потому что будет вызываться конструктор по умолчанию, и объект будет инициализирован.


Теперь рассмотрим эту структуру,

struct C
{
   const int i;
   C() {}
};

C определенно является не-POD-типом, поскольку он имеет определяемый пользователем конструктор. Также обратите внимание, что в конструкторе он не инициализирует i, который int, объявленный как const. Из-за этого неинициализированного const я следующее сообщение получило бы ошибку:

const C c; //error - 

Можно подумать, что ошибка связана с const в приведенном выше объявлении переменной C. Но это близорукость и не соответствует действительности. Даже если вы удалите const, это даст ошибку:

C c; //error - same error

Ошибка из-за C::i, которая объявлена ​​const, но не была инициализирована.

Демо: http://ideone.com/NJT8L


Этот анализ также демонстрирует, что встроенные типы не автоматически инициализируются, даже если они являются членами типов, отличных от POD. Это относится и к типам классов, отличных от POD.

И синтаксис инициализации по умолчанию для встроенных типов (и типов POD) заключается в следующем:

struct C
{
    const int i;
    C() : i() {} //note the syntax - it is called member-initialization list
};

Теперь это разрешено:

C x; //ok
const C y; //ok

Демо: http://ideone.com/84vD9


Что касается того, что делает struct/class POD, см. этот раздел:

Ответ 2

Потому что, если вы можете назначить их позже, они не будут "const".

Ответ 3

Назначение переменной const в программе не допускается, потому что тогда вы можете изменить ее значение, которое, очевидно, неверно!!!!

Следовательно, вам нужно инициализировать их.

надеюсь, что это поможет

Ответ 4

Если переменная объявлена ​​как const, это означает, что переменная доступна только для чтения и не может быть изменена .so, чтобы сделать переменную только для чтения, она должна быть инициализирована в момент объявления.

Для лучшего понимания переменных смотрите следующую программу

Каждый процесс состоит из 4 частей адресного пространства, доступных для процесса, когда он работает

Текст. Эта часть содержит фактические инструкции m/c для выполнения. Во многих операционных системах это значение устанавливается только для чтения, так что процесс не может изменить свои инструкции. Это позволяет нескольким экземплярам программы делиться одной копией текста.

Данные. Эта часть содержит часть данных программы. Он делится на

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

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

3) Uninitalized Data - это содержит элементы, которые не инициализируются программой и установлены до того, как процессы выполняются. Они также могут быть изменены и обозначены как BSS (Block Started Symbol). Адресом таких элементов является то, что системе не нужно выделять пространство в программном файле для этой области, b'coz он инициализируется оператором ОС до того, как процесс начнет выполнение.

Stack - эта часть используется для локальных переменных, фреймов стека

Куча - эта часть содержит динамически выделенную память

int abc = 1;                            ---->   Initialized Read-Write Data
char *str;                              ---->   BSS
const int i = 10;                       ----->  Initialized Read-Only Data

main()
{
    int ii,a=1,b=2,c;                            ----->  Local Variables on 
Stack

    char *ptr;
    ptr = malloc(4);                     ------> Allocated Memory in Heap

     c= a+b;                             ------> Text

}

Данные, данные хранилища Текст, код сохранения

Есть 3 (основных?) сегмента/секций файла, созданного компоновщиком. текст - текст программы (и, по-видимому, const char массивы, возможно, другие массивы 'const', поскольку они не могут быть изменены в любом случае). Я не уверен на 100% в части массива, может быть, кто-то меня исправит.

данные - инициализированные глобальные данные. см. примеры ниже. bss - неинициализированные глобальные данные. Вот несколько примеров

int x = 1;    /* goes into data */
int y;        /* goes into bss  */
const int z = 1;/* goes into text */

это мы видели в тексте, так как не можем быть изменены в любом случае, но можем быть защищены