没有新的C++对象

Hen*_*y B 63 c++ new-operator

这是一个非常简单的问题,但我多年来都没有正确地完成c ++,所以我对此感到困惑.此外,在互联网上查找并不是最简单的事情(至少对我而言).

为什么不使用new关键字,它是如何工作的?

基本上,这里发生了什么?

CPlayer newPlayer = CPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

Ara*_*raK 54

这个表达式:

CPlayer(position, attacker)
Run Code Online (Sandbox Code Playgroud)

CPlayer使用上面的构造函数创建一个类型的临时对象,然后:

CPlayer newPlayer =...;
Run Code Online (Sandbox Code Playgroud)

使用复制构造函数将上述临时对象复制到newPlayer.更好的方法是编写以下内容以避免临时性:

CPlayer newPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

  • 编译器是否要删除副本(在允许的情况下)取决于编译器.12.8/15. (8认同)
  • 实际上编译器可能会优化它.在这种情况下,不会调用复制构造函数.http://stackoverflow.com/questions/1758142/why-copy-constructor-is-not-called-in-this-case (5认同)
  • 声明中的赋值效率不比使用构造函数语法低.如果他们是单独的陈述,那么关于临时的评论就是正确的.本质上,它声明了一个CPlayer(通常在堆栈上),而不是从免费存储(堆)为它分配空间. (5认同)
  • 我认为这个答案并不完全正确。OP 的代码*看起来*像是创建一个临时文件然后复制它,但标准 12.1.11 另有建议。jleedev 发现这只是一个普通的构造函数调用。 (2认同)

Tim*_*sch 45

以上构造堆栈上的CPlayer对象,因此它不需要new.new如果您尝试在堆上分配CPlayer对象,则只需使用.如果您正在使用堆分配,代码将如下所示:

CPlayer *newPlayer = new CPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,我们使用指向CPlayer对象的指针,需要通过匹配调用来清理它delete.当堆栈超出范围时,将在堆栈上分配的对象自动销毁.

实际上写起来会更简单,更明显:

CPlayer newPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

很多编译器都会优化你发布到上面的版本,并且阅读起来更清楚.

  • 我认为这是不正确的:“在堆上分配的对象在超出范围时将自动销毁。” (2认同)
  • 你是对的,我的意思是写“堆栈”,而不是“堆”。感谢您指出了这一点。 (2认同)

Mic*_*fik 10

CPlayer newPlayer = CPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

此行创建一个CPlayer类型的新本地对象.尽管它具有类似功能的外观,但它只是调用了CPlayer的构造函数.不涉及临时或复制.名为newPlayer的对象与它所包含的作用域一样长.在new这里不使用关键字,因为C++不是Java.

CPlayer* newPlayer = new CPlayer(position, attacker);
Run Code Online (Sandbox Code Playgroud)

此行在堆上构造CPlayer对象,并定义一个名为newPlayer的指针以指向它.对象一直存在,直到某人为止delete.

  • "没有涉及临时或复制" - 这不完全正确.没有这样的保证.但每个体面的编译器都应该忽略副本. (2认同)

dig*_*ter 5

newPlayer不是动态分配的变量,而是一个auto,stack-allocated变量:

CPlayer* newPlayer = new CPlayer(pos, attacker);
Run Code Online (Sandbox Code Playgroud)

不同于

CPlayer newPlayer = CPlayer(pos, attacker);
Run Code Online (Sandbox Code Playgroud)

通过普通的CPlayer(位置,攻击者)构造函数调用在堆栈上分配newPlayer,虽然比通常有点冗长

CPlayer newPlayer(pos, attacker);
Run Code Online (Sandbox Code Playgroud)

它与说法基本相同:

int i = int(3);
Run Code Online (Sandbox Code Playgroud)

  • 小心点.这是一个"复制初始化".这不是*一项任务. (2认同)
  • 当然,复制文件(至少在逻辑上)涉及到.你会注意到,如果你把你的副本ctor私有.然后,此复制初始化将不再起作用.即使编译器能够优化副本,C++标准也需要可访问的副本. (2认同)