Почему константные переменные должны быть инициализированы сразу? - PullRequest
13 голосов
/ 09 декабря 2011

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

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

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

Может кто-нибудь объяснить это мне, пожалуйста?

Ответы [ 4 ]

21 голосов
/ 09 декабря 2011

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

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 i следующее выдаст ошибку:

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


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

4 голосов
/ 09 декабря 2011

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

0 голосов
/ 09 декабря 2011

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

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

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

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

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

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

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

3) Неинициализированные данные. Содержит элементы, которые не были инициализированы программой и имеют значение 0.до выполнения процессов.Они также могут быть изменены и обозначены как BSS (символ начала блока).Преимуществом таких элементов является то, что системе не нужно выделять место в программном файле для этой области, потому что она инициализируется в 0 операционной системой до того, как процесс начнет выполняться.

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

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

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 (main?) сегменты / разделы файла, создаваемые компоновщиком.текст - текст программы (и, видимо, массивы const char. возможно, другие массивы 'const', так как они не могут быть изменены в любом случае).Я не уверен на 100% в части массива, возможно, кто-то меня поправит.

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

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

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

0 голосов
/ 09 декабря 2011

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

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

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

...