2013-11-07 3 views
0

я прочитал книгу С. Липпман «внутри объекнтых моделей ++», есть такой кодОбъект, созданный на куче, не является глобальным?

class Foo { public: int val; Foo *pnext; }; 
void foo_bar() 
{ 
// Oops: program needs bar's members zeroed out 
Foo bar; 
Foo* baz = new Foo(); // this line i added myself 
if (bar.val || bar.pnext) 
// ... do something 
// ... 
} 

, и он говорит, что «конструктор по умолчанию не синтезируется для этого фрагмента кода.

Глобальных объекты гарантируют, что их связанная память «обнулена» при запуске программы. Локальные объекты , выделенные в стеке программ, и объекты кучи, выделенные в свободном хранилище, не имеют связанной с ними памяти , а память сохраняется произвольная битовая диаграмма предыдущего использования ».

В этом коде объект baz был создан в куче, и в соответствии с тем, что было сказано выше, этот объект не является глобальным, и он не будет называться конструктором по умолчанию. Я правильно понимаю?

+1

Это не глобальный, но его значения * будут * обнулены. – juanchopanza

ответ

1

Скобки в new Foo() указать значения инициализируются; это в основном означает, что каждый элемент инициализируется нулем. Если вместо этого вы сказали new Foo, то члены останутся неинициализированными, так как они предназначены для вашей автоматической переменной.

К сожалению, для инициализации значения автоматической переменной вы не можете написать Foo bar(), так как это объявляет функцию. Вам понадобится

Foo bar{};  // C++11 
Foo bar = Foo(); // Historical C++ 
0

Если класс не имеет конструктора по умолчанию (и никакого другого конструктора), компилятор создаст его для вас. Он должен, или вы не сможете создавать экземпляры класса. Однако созданный конструктор по умолчанию ничего не сделает.

Что добавление пустого набора скобок в new Foo() делает, является дорожить инициализировать выделенный объект, который означает, что члены инициализируются в их значение «по умолчанию», который равен нуль для целых и чисел с плавающей точкой, и nullptr для указателей ,

1

Когда вы сделаете это:

Foo* baz = new Foo(); 

вы динамически выделяя Foo экземпляр и значения инициализации его. Для POD это означает, что члены получают нуль-инициализацию. Если бы ты сказал, что это (при условии, не глобальный контекст):

Foo* baz = new Foo; 

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

Это также относится и к автоматическим случаях хранения:

Foo f0; // default initializaiton: members not zeroed out. 
Foo f1 = Foo(); // value initialization: members zeroed out. 
Foo f2{}; // C++11 value initialization: members zeroed out. 
Foo f3(); // Ooops! Function declaration. Something completely different. 
+0

Следует отметить, что эта инициализация значения является добавлением C++ 11. Раньше, насколько мне известно, пустые круглые скобки не имели особого значения, а также выполняли бы конструктор по умолчанию, который ничего не делает, не так ли? – codeling

+0

@nyarlathotep нет, это неверно. Он находится в C++ 03. – juanchopanza

+0

О, хорошо, спасибо, что очистили это! – codeling

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