2010-06-14 4 views
5

Я хочу знать, в C++, когда происходит инициализация объектов?
Это время компиляции или время ссылки?
Для экс:инициализация объектов в C++

//file1.cpp 
extern int i; 
int j=5; 

//file2.cpp (link with file1.cpp) 
extern j; 
int i=10; 

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

ответ

2

На самом деле существуют разные случаи:

  • глобальные переменные или статические переменные (не классы): эти значения хранятся в секции init exe/dll. Эти значения создаются компоновщиком на основе информации об обобщенных объектных файлах. (инициализация при загрузке + отображение dll/exe в память)
  • локальные нестатические переменные: эти значения задаются компилятором путем помещения этих значений в стек (push/pop on x86) (инициализация компилятора)
  • объектов : память зарезервирована в стеке, фактическая установка значений отложена на вызов конструктора (инициализация времени выполнения)
  • указатели на объекты (на самом деле это не новый случай): пространство зарезервировано только для указателя. Указанный объект существует только после вызова нового, который резервирует память, и вызывает конструктор для его инициализации (инициализация времени выполнения)
+0

Что относительно членов «static const» (а не классов)? Действительно ли они существуют как «переменная»? Я думаю, что каждое их использование просто заменяется значением, а «статическая константная переменная» просто исчезает. Правильно? Для остальных, хороший обзор, +1. – Patrick

+0

Хорошо .. Так в коде выше ... будет ли что-то случится? 1. при компиляции файла file1.cpp компилятор уходит из i, так как он не распределяет память для i. 2. компилятор выделяет хранилище для j, но не инициализирует его. 3. При компиляции file2.cpp компилятор уезжает j, так как это i.e не выделяет для него хранилище. 4. компилятор выделяет хранилище для i, но не инициализирует его. 5. При связывании file1.o и file2.o теперь пусть сначала инициализируется file2.o, так что теперь: Получает ли j начальное значение 0? или не инициализируется? –

+0

@Patrick, хороший момент, я не знаю точно. Я думаю, вы правы, поскольку стоимость наличия переменной выше, чем встроенное значение для базовых типов. Однако не 100% уверены, что все компиляторы ведут себя так ... – jdehaan

0

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

+0

Но я прочитал в книге, что компилятор не может определить, что будет стоить в поэтому мы не можем использовать что-то вроде этого: int a = 5; int arr [a]; –

+0

@Happy Если компилятор выполнил достаточно статического анализа, чтобы понять, что это может быть преобразовано в 'int arr [5];' было бы хорошо, но обычно они не могут (это может даже не разрешаться спецификацией) –

+0

причина для int a = 5; int arr [a]; не определяется, потому что размер массива не определен. Позже вы можете изменить до 10 в тот момент, как вы думаете, что компилятор изменит ранее объявленный размер. – ckv

0

В вашем примере нет объектов, только int s. Если при инициализации вы имеете в виду, когда назначены их значения, то int s будут преобразованы в записи размера слова в разделе данных в объектном файле, которые будут жестко закодированы с их начальными значениями. Раздел данных, наряду с остальной частью объектного файла, создается компилятором, поэтому я полагаю, что ответ на ваш вопрос времени компиляции

+0

если u рассмотреть OOP, тогда мы можем сказать int также как класс. – ckv

+0

@vis Ints не являются классами на C++, они являются примитивным типом; нет вызова конструктора или любого другого леса, связанного с классами –

+0

Правильно. Я понимаю. возможно, мы должны изменить вопрос на Инициализацию переменных, а не объектов. – ckv