Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.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++;对象在作用域块结束之前销毁?_C++_Scope_Destructor - Fatal编程技术网

C++ 为什么不命名C++;对象在作用域块结束之前销毁?

C++ 为什么不命名C++;对象在作用域块结束之前销毁?,c++,scope,destructor,C++,Scope,Destructor,下面的代码打印一、二、三。对于所有C++编译器来说,这是不是真的? class Foo { const char* m_name; public: Foo(const char* name) : m_name(name) {} ~Foo() { printf("%s\n", m_name); } }; void main() { Foo foo("three"); Foo("one"); // un-named object

下面的代码打印一、二、三。对于所有C++编译器来说,这是不是真的?

class Foo
{
      const char* m_name;
public:
      Foo(const char* name) : m_name(name) {}
      ~Foo() { printf("%s\n", m_name); }
};

void main()
{
      Foo foo("three");
      Foo("one");   // un-named object
      printf("two\n");
}

这样的临时对象的范围只有一行。想想看,线结束后,你就不能再引用它了,那么为什么对象会留在周围呢


如果不是这样,编译器将无法优化函数调用中的临时对象。

临时变量将一直存在到创建它的完整表达式结束。你的以分号结尾

这在12.2/3中:

临时对象作为计算完整表达式(1.9)的最后一步被销毁,完整表达式(1.9)包含创建临时对象的点

你的行为是有保证的

有两个条件,如果满足,将延长临时文件的使用寿命。第一个是当它是对象的初始值设定项时。第二个是当引用绑定到临时引用时。

是的,这是需要的

Foo-Foo(“三”)
创建一个普通对象,该对象将在作用域结束时被销毁

Foo(“one”)
创建一个临时对象,该对象在指令[1]末尾被销毁。为什么?因为在指令结束后,您无法访问它


[1] 有意简化:我应该说的是序列点。

管理临时对象生命周期的规则与范围的概念无关。作用域是名称的属性,临时对象没有名称。换句话说,临时对象没有作用域

大多数情况下,临时对象的生存期在创建该对象的完整表达式结束时结束,这就是您在实验中观察到的。这是有一些例外的一般规则。主要的一点是,如果您立即将引用附加到临时对象,则该对象的生存期将延长,以匹配引用的生存期

const Foo &rfoo = Foo("one");

由于标准委员会的失误,上述临时文件将在
rfoo
的生命周期内继续存在。

。它这样做是因为他们选择了让它这样做。它的定义是这样做。它应该被视为一个匿名实例,其作用域与它被命名时的作用域相同。从实例化点到块的末尾。显然,他们认为唯一的用途是将临时变量传递到函数中,在函数调用结束时,临时变量被推到堆栈上并从堆栈中弹出


未命名对象仍应推送到堆栈上,并保持在堆栈上,直到块结束,从而在需要时将其弹出堆栈。在单个语句中构造和销毁对象是毫无意义的。我希望看到一个实例/案例,其中这是实际有用的。如果在阻塞期间它不在范围内,那么它肯定是一个错误,至少应该生成一个警告。

序列点与此无关。即使在创建对象的“指令”的末尾有一个序列点,临时表达式的生存期也会在完整表达式的末尾结束。例如,在
Foo(“a”)、Foo(“b”)、Foo(“c”)Scope是一个名称的属性,临时对象没有名称。
临时对象的生存期是否使用out
const
限定符扩展绑定到引用<代码>Foo&rfoo=Foo(“一”)
我读到,临时文件的生命周期只能通过绑定到
const
引用来延长。但该示例在VS 2010上运行良好,但在gcc上不起作用(两种情况下的
this
在给定链接中也是相同的,表示即使VS上没有out
const
限定符,也可以临时延长寿命)。GCC还是VS正确?@ MaHash:代码不能在标准C++中编译,这就是GCC拒绝它的原因。VS接受它作为扩展,只是因为您启用了扩展。如果在VS中禁用语言扩展,代码也不会在VS中编译;完全可以使用一个不使用堆栈的C++实现,而是在静态位置分配所有的东西。小的临时值也可以在寄存器中传递,而不是在可寻址内存中。“在一条语句中构造和破坏对象是毫无意义的。”如果你这样做是为了产生副作用,或者是在转换链中。它非常有用,像Firefox这样的主要C++项目可能会有成千上万个这样的结构。它们非常有用。如果这些对象一直保留到块的末尾,那就太糟糕了,缓存压力会破坏许多项目的性能,即使总体内存使用情况不会发生显著变化。