Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';c+中int i=0,int i(0),int*p=new int,int*p=new int(0)之间的s差+;_C++ - Fatal编程技术网

C++ 什么';c+中int i=0,int i(0),int*p=new int,int*p=new int(0)之间的s差+;

C++ 什么';c+中int i=0,int i(0),int*p=new int,int*p=new int(0)之间的s差+;,c++,C++,两者有什么区别 int i=0; 及 及 int*p=newint仍然是复制初始样式吗 何时使用inti=0notnew int(0)?new意味着堆内存分配(可能会泄漏),所以不,您不想一直这样做 inti=0和inti(0)是等效的,但取决于实现,第一个可以使用赋值运算符,而第二个可以使用值构造。这可以让编译器针对目标体系结构进行优化。在类的情况下,赋值方法可能会慢一些,因为它将创建一个类(通常带有默认值),然后它将执行赋值并清除它刚刚分配的所有默认值 有人可能会插话并参考语言规范以获得

两者有什么区别

int i=0; 

int*p=newint
仍然是复制初始样式吗


何时使用
inti=0
not
new int(0)

new
意味着堆内存分配(可能会泄漏),所以不,您不想一直这样做

inti=0
inti(0)
是等效的,但取决于实现,第一个可以使用赋值运算符,而第二个可以使用值构造。这可以让编译器针对目标体系结构进行优化。在类的情况下,赋值方法可能会慢一些,因为它将创建一个类(通常带有默认值),然后它将执行赋值并清除它刚刚分配的所有默认值


有人可能会插话并参考语言规范以获得更准确的答案。

new
意味着堆内存分配(可能会泄漏),因此不,您不想一直这样做

inti=0
inti(0)
是等效的,但取决于实现,第一个可以使用赋值运算符,而第二个可以使用值构造。这可以让编译器针对目标体系结构进行优化。在类的情况下,赋值方法可能会慢一些,因为它将创建一个类(通常带有默认值),然后它将执行赋值并清除它刚刚分配的所有默认值


有人可能会在语言规范中加入和引用更准确的答案。

< P>在C和早期C++中,只能使用int i=0;
inti(0)模式与常规类型的构造函数相同

T i(0);

因此,它被添加为
int i=0的替代品看起来不像一般的构造函数模式。这在使用模板时非常有用。因此,模板可以使用int和类。在c和早期C++中,

< p>只能使用int i=0;
inti(0)模式与常规类型的构造函数相同

T i(0);

因此,它被添加为
int i=0的替代品看起来不像一般的构造函数模式。这在使用模板时非常有用。因此模板可以使用int和类。

我将首先回答一个稍微不同的问题

假设您有一个
结构
(它们几乎相同),如下所示:

struct Foo {
  int value; // Foo stores an int, called value
  Foo(int v):value(v) {}; // Foo can be constructed (created) from an int
  explicit Foo(double d):value(d) {}; // Foo can be constructed (created) from a double
  // ^^^ note that keyword.  It says that it can only be EXPLICITLY created from a double
};
现在,这很像
int
,但有一些区别

Foo i = 0;
上面创建了一个
int
literal,然后使用
Foo(intv)
构造函数构造
fooi

Foo i(0);
上面创建了一个
int
literal,然后使用
Foo(intv)
构造函数构造
fooi
。注意,我只是重复了我自己

Foo i = Foo(0);
上面创建一个
int
literal,然后使用
Foo(intv)
构造函数构造
fooi
,然后从中复制构造
fooi
。但是,该标准允许编译器“省略”(跳过)复制构造函数,而只是直接从
int
literal
0
构造
fooi

Foo* i = new Foo;
这将进入空闲存储(通常实现并称为堆),获得足够的内存来存储
Foo
,然后默认构造它。然后它返回此
Foo
对象的地址,然后使用该地址初始化指针
Foo*i
。现在,请注意
Foo
的默认构造函数未初始化
value
。这是我在上述
Foo
实现中的一个缺陷(在我看来),除非在特殊情况下,否则您很少希望这样做

令人烦恼的是,整数(
char
int
long
无符号字符
,等等),浮点(
double
float
)文本和指针文本都共享此属性——默认情况下,它们不会初始化为任何值

因此,您应该确保它们已显式初始化。对于
Foo
,添加一行:

Foo():value() {}
这就足够了

Foo* i = new Foo(0);
这将进入空闲存储(通常实现并称为堆),获得足够的内存来存储
Foo
,然后使用整数文本0构造它。然后它返回此
Foo
对象的地址,然后使用该地址初始化指针
Foo*i

现在,免费存储中的内存通常会保留下来供您使用,直到您有时间归还它,或者您的程序关闭。为了返回它,您在同一个指针上调用
delete
,这两种情况下,对象(
Foo
在本例中)的析构函数都被调用(
Foo
没有析构函数,因此这被跳过),然后内存被返回到空闲存储区,供以后调用
new
使用

跟踪这一点是一件非常痛苦的事情,也是一大堆错误的根源,因此您应该避免调用
new
。有很多方法可以避免调用
new
,包括使用
std::vector
来管理内存块,或者使用
shared_ptr
make_shared
在堆上创建对象,这些对象通过一种称为RAII的技术来管理自己的生命周期,或者,当您希望对指针的生命周期进行密切控制时,可以使用
unique\u ptr
(遗憾的是,
make\u unique
不存在)

现在让我们更进一步

Foo i = 0.0;
这无法编译。我说过
Foo(double)
的构造函数是显式的,上面只选择调用非显式的构造函数。另一方面:

Foo i(0.0);
Foo i = Foo(0.0);
它们都愿意调用显式构造函数,并且工作得很好

东北
Foo i(0.0);
Foo i = Foo(0.0);
Foo i{0.0};
Foo i = {0};
int i = 0;
int i(0);
int i = int();
int i();
int i{};
int* p = new int;
int *p=new int(0);
int x(int());
int x();
int i=0; 
int i(0);
int *p=new int; 
int *p=new int(0);