#include <cstdio>
struct smth
{
int value;
smth() : value(0) { puts("Constructor called"); }
};
struct defctr
{
int value;
};
#define CHECK(TYPE, ARGS, VALUE) do \
{ \
TYPE *x = new TYPE ARGS; \
printf("%p %08X new %s%s\n", (void*)x, VALUE, #TYPE, #ARGS); \
delete x; \
} while(0)
int main()
{
CHECK(int, (-1), *x);
CHECK(int, , *x);
CHECK(int, () , *x);
CHECK(defctr, , x->value);
CHECK(defctr, (), x->value);
CHECK(smth, , x->value);
CHECK(smth, (), x->value);
return 0;
}
0x8110438 FFFFFFFF new int(-1)
0x8110438 93939393 new int
0x8110438 00000000 new int()
0x8110438 93939393 new defctr
0x8110438 00000000 new defctr()
Constructor called
0x8110438 00000000 new smth
Constructor called
0x8110438 00000000 new smth()
void foo()
{
int x; // Не инициализирован.
int x{}; // 0
void *x; // Не инициализирован.
void *x{}; // nullptr
struct A
{
int f;
int g = 1;
// Не влияет на результат:
// A() = default;
};
A a; // f не инициализирован, g = 1
A a{}; // f = 0, g = 1
struct B
{
int f;
int g = 1;
int h;
B() : h(2) {}
};
B b; // f не инициализирован, g = 1, h = 2.
B b{}; // f не инициализирован, g = 1, h = 2.
}
关于新
对于具有非默认构造函数的类型,没有区别。但是对于内置类型和具有默认构造函数的类型,带括号的版本将被初始化为零,没有括号的版本将保持内部垃圾。
http://codepad.org/vYwvxMn5
没有新的
这是一个变量:
这是函数原型:
首先,
S s();
它是一个函数声明,而不是一个对象声明(参见最令人烦恼的解析)。要将其视为对象,您可以执行
S s = S();
或S s{};
,含义相同。其次,除了
()
您也可以使用它们之外{}
,它们的行为方式相同。唯一的区别是{}
大多数令人烦恼的解析不受影响。第三,
new
它不会改变括号的含义(但会删除可能最令人烦恼的解析)。如果
S
是数字类型、、enum
指针或指向成员的指针,则附加()
(或{}
)会将其初始化为零。否则,它保持未初始化状态。如果
S
是您自己为其编写了默认构造函数的类,则添加()
(或{}
) 不会改变任何内容。如果
S
是编译器为其生成默认构造函数的类(也就是说,您根本没有为它声明构造函数,或者您将默认构造函数标记为=default
在类主体中:)S() = default;
,然后添加()
(或{}
)初始化所有字段否则将保持为零将未初始化(即,未指定默认初始化程序的那些字段)。以上不适用于全局/静态对象 - 它们(及其字段)永远不会未初始化。如果它们(或它们的某些字段)未初始化,则将它们设置为零。
例子: