C++ 临时对象有作用域吗?

C++ 临时对象有作用域吗?,c++,object,scope,temporary,lifetime,C++,Object,Scope,Temporary,Lifetime,名称具有作用域(编译时属性),而对象具有生存期(运行时属性)。对吧? 我经常看到人们谈论临时对象“超出范围”。但由于临时对象没有名称,我认为在本文中谈论“范围”是没有意义的。临时对象的生存期与作用域无关。你同意吗?我见过有人说“一个对象超出了范围”,用你的说法,这意味着“当对象的名称超出范围时,对象的生命周期就结束了”。如果您使用这种简短形式,很自然地会说temporay对象也超出了范围。临时对象确实有名称,尽管只能由编译器引用。否则编译器将如何引用它们?只是因为你不能引用一个实例化后的临时文件

名称具有作用域(编译时属性),而对象具有生存期(运行时属性)。对吧?


我经常看到人们谈论临时对象“超出范围”。但由于临时对象没有名称,我认为在本文中谈论“范围”是没有意义的。临时对象的生存期与作用域无关。你同意吗?

我见过有人说“一个对象超出了范围”,用你的说法,这意味着“当对象的名称超出范围时,对象的生命周期就结束了”。如果您使用这种简短形式,很自然地会说temporay对象也超出了范围。

临时对象确实有名称,尽管只能由编译器引用。否则编译器将如何引用它们?只是因为你不能引用一个实例化后的临时文件,并不意味着编译器不能引用它

f(Foo(), Bar());

编译器必须引用至少一个临时变量,即使您作为程序员不能引用其中任何一个。临时对象确实有一个作用域。

绑定到常量引用会将临时对象的生存期延长到引用的生存期,因此在某种意义上,在这种特定情况下,它确实与作用域有关:

std::string foo();

int main()
{
    // Lifetime of the temporary returned by foo is indeed the scope of bar
    const std::string &bar = foo();
}
见赫伯·萨特:

通常,一个临时对象是持久的 只有到了满月底 它出现的表达式。 但是,C++故意指定 将临时对象绑定到 对堆栈上常量的引用 延长设备的使用寿命 临时的,临时的 引用本身,从而避免 否则将是一种普遍现象 悬挂参考错误


临时词语的使用寿命与句法块关系不大,但“范围”——作为一个词而不是一个技术术语——可以用在其他方面。重要的问题是,当人们使用“范围”来指代临时术语时,你是否感到困惑。(从我的角度看,你似乎不是。)

既然你说的是用这个词与他人交流,那么这种交流才是真正重要的。如果您是通过编写standardese文档来定义术语,或者试图在定义术语的上下文中解释此类文档,则情况会有所不同。当然,解释ISO 14882需要与其他人沟通,因此在这种情况下,如果必要,您只需要求澄清

让所有非标准的通信都成为标准的通信是适得其反的,而且在需要高精度的情况下,在任何一种情况下都最好使用代码。C++标准为此广泛使用实例。 例如,经常使用“调用构造函数”,但从技术上讲,您不能直接调用构造函数;相反,构造函数是对象初始化的一部分。这就是为什么会有一种明确的新形式来构造一个对象。(有趣的是,你可以直接调用析构函数。)然而,我希望这个短语在大多数上下文中都能被理解,尽管我不主张在标准上下文中使用它

名称具有作用域(编译时属性)

对。我不认为这是一种财产思想。但基本上是的

而对象具有生存期(运行时属性)。对吧?

有三种类型的变量。每种类型在生命周期方面都有不同的属性

  • 自动存储持续时间:
  • 静态存储时间
  • 动态存储持续时间
注意:自动存储持续时间对象的生存期绑定到变量的范围

我经常看到人们谈论临时对象“超出范围”

除非绑定到变量,否则将在表达式末尾销毁临时变量。如果它们绑定到一个变量(常量引用),则它们与该变量具有相同的寿命。有时将其称为范围更容易,但从技术上讲,您是正确的

但由于临时对象没有名称,我认为在本文中谈论“范围”是没有意义的

技术上是的。但我认为这只是让谈论它更容易。对我来说(虽然技术上不正确),临时(未绑定)的范围是表达式。这比临时变量的寿命更容易说

临时对象的生存期定义非常明确,与范围无关。你同意吗


对。但谈论范围仍然感觉更自然(即使在技术上不正确)。大多数人都明白你的意思。但是,当你开始谈论非常技术性的东西时,你应该使用正确的术语,在这个上下文中范围是不正确的。

但是临时对象在创建它的词汇上下文中没有名称,因此没有任何名称可以超出范围:)显然不是。关键是,术语“对象超出范围”通常适用于其生存期未通过
delete pObject
显式终止的任何对象。按照这种逻辑,数组的每个成员都需要一个名称。然而,我们知道编译器可以通过地址引用数组的成员。临时表的工作原理是一样的:编译器知道它们的地址和类型,这就足够了。