Два способа назвать конструктора по умолчанию

Обратите внимание std::vector не делает проверки диапазона также.

5
задан mt_serg 9 October 2009 в 09:53
поделиться

5 ответов

Default constructor for POD types fills it with zeros. When you explicitly define your own constructor you are not initialize x and y and you'll get random values (in VS debug they are filled with exact values, but in release they will be random).

It is according to C++03 Standard 8.5/5:

<...>To value-initialize an object of type T means:
- если T является типом класса (пункт 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- в противном случае объект инициализируется нулем .

B () - это временная инициализация значения, которая будет использоваться при инициализации копии b1 .

В B b2 не указан инициализатор для объекта, поэтому согласно стандарту C ++ 03 8.5 / 9:

Если для объекта не указан инициализатор , и объект имеет (возможно, cv-квалифицированный) тип класса, отличный от POD (или его массив), объект должен быть инициализирован по умолчанию; если объект имеет тип, определяемый константой, базовый тип класса должен иметь конструктор по умолчанию, объявленный пользователем. В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение ; если объект или любой из его подобъектов относятся к типу с определением const, программа сформирована неправильно.

10
ответ дан 18 December 2019 в 07:55
поделиться

In both cases, this statement defines b1 and copy-intializes it from a value-initialized temporary B object.

B b1 = B();

When B doesn't have a user-declared constructor, value-initializing causes call of B's members to be value-initalized, and for simple types, such as int, this means zero-initializing.

When B does have a user-declared constructor, value-initializing tries to call the default constructor. If the members x and y are not listed in the constructor initializer list, then they are left uninitialized.

B b2;

In functions, local objects of POD-type without an initializer are left uninitialized. When you don't define a constructor for B, it is a POD-class so this applies and the values of b2.x and b2.y have indeterminate values.

If the object is of non-POD class type, then it is default-initialized, but if this calls a constructor which leaves its members uninitialized then this makes no difference.

5
ответ дан 18 December 2019 в 07:55
поделиться

This is value-initialization versus no initialization. If you write

B b1 = B();

you get copy-initialization with a "value-initialized" temporary -- B(). Value-initialization of class-type objects invokes a user-defined constructor (if existant) or otherwise value-initializes the members. Value-initialization of scalar type objects is equivalent to zero-initialization. When you declare your own constructor that doesn't do anything, your scalar members are not initialized.

B b1;

is a default-initialization or no initialization at all (depending on B).

The exact initialization rules are rather complicated. See C++ standard section 8.5 "Initializers".

3
ответ дан 18 December 2019 в 07:55
поделиться

i tried on vc6 and Visual Studio 2005 i am getting below result in both:Could you please post disassemble code generated , Like below i have posted disassemble code for 2005

x:-858993460

y:-858993460


x:-858993460

y:-858993460


 B b1 = B(); //init1
0043DEDE  lea         ecx,[b1] 
0043DEE1  call        B::B (43ADD9h) 
 B b2; //init2
0043DEE6  lea         ecx,[b2] 
0043DEE9  call        B::B (43ADD9h) 

 print(b1);
0043DEEE  lea         eax,[b1] 
0043DEF1  push        eax  
0043DEF2  call        print (43A302h) 
0043DEF7  add         esp,4 
 print(b2);
0043DEFA  lea         eax,[b2] 
0043DEFD  push        eax  
0043DEFE  call        print (43A302h) 
0043DF03  add         esp,4 
0
ответ дан 18 December 2019 в 07:55
поделиться

О объясняет Кирилл

Другое значение: -858993460 - 0xCCCCCCCC, это значение по умолчанию для неинициализированной стековой памяти в отладочных сборках VC.

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

Теперь я должен признать, что не знал, что можно вызывать c'tor напрямую, как это делается в вашем примере! И я бы поклялся, что это незаконно ...

2
ответ дан 18 December 2019 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: