在这个初始化过程中创建了多少临时对象?

Posted

技术标签:

【中文标题】在这个初始化过程中创建了多少临时对象?【英文标题】:How many temporary objects are created in this initialization? 【发布时间】:2019-04-26 12:19:49 【问题描述】:

我有这个初始化:

const char* str = std::string("a").c_str();

本次初始化创建了多少临时对象?

"a" 可以被视为临时工吗?对象?

我知道std::string("a") 是临时工。对象。

c_str() 的结果是一个对象,str 存储它。所以这不是临时工。对象,对吧?

【问题讨论】:

临时的std::string是唯一的临时对象,而str是这个之后的悬空指针 我认为指针是对象。 @JoãoPaulo 他们是。但是,作为纯右值,初始化程序被具体化为 str ,没有临时对象。在 C++17 之前有一个 看起来像纯右值are no longer materialized。 @wally 谢谢沃利。不过,我对这个词有点怀念。 【参考方案1】:

"a"const char[2]类型的字符串字面量,所以它是一个对象。

std::string("a") 是一个纯右值表达式并且不是一个临时对象(目前)。当您调用c_str() 时,您会具体化一个临时对象并在其上调用c_str(),以获取指向临时对象数据的指针。

然后您将指针的地址分配给str,所以现在str 将地址保存到指向临时对象数据的指针。在该完整表达式的末尾,物化临时对象被销毁,使对该临时数据的迭代器/指针/引用无效。

这意味着str 现在指向您不再拥有的内存,称为悬空指针。除了给它分配一个不同的地址之外,对它做任何事情都是未定义的行为。

所以当一切都结束时,你有 2 个对象。一个悬空指针 (str) 和一个字符串字面量 ("a")。

【讨论】:

【参考方案2】:

只有一个。字符串。

"a" 是一个字面量,它的类型是const char[],大小合适,它有一个静态存储。所以,这肯定不是暂时的。

str,返回值c_str() 也是const char 指针。

没有创建其他对象。

【讨论】:

"a" 是一个字面量,以 const char* 表示。所以它不能被认为是一个对象。 这是错误的。字符串字面量是一个左值const char[N] 数组,所以它是一个对象。 @JoãoPaulo 不会。它将在程序的整个生命周期内一直存在。 @luk32 它被标准明确称为一:timsong-cpp.github.io/cppwp/lex.string#15 @curiousguy 什么?该标准说对象具有静态存储持续时间,从上面指定的给定字符初始化。所以它有一个定义的生命周期(静态对象从它们第一次遇到到程序结束)并且它被初始化。 @curiousguy 抱歉,这是完全错误的。如果你愿意,你可以问一个 Q 并得到一个明确的答案。如果使用字符串文字是 UB,那么基本上所有程序都是 UB。字符串字面量是对象的定义,对象的生命周期在第一次遇到字符串字面量时开始。【参考方案3】:

"a" 可以被视为临时工吗?对象?

从技术上讲,定义不明确

它确实没有有一个定义的生命周期。从技术上讲,使用它已经定义了行为。 不是正式开始对象生命周期的构造。

实际上你可以使用它(显然)。

【讨论】:

对不起所有的反对者,这是真的; std 中没有任何内容表明"a" 的生命周期开始了。没有。字面意思,就是使用字符串句号是UB。

以上是关于在这个初始化过程中创建了多少临时对象?的主要内容,如果未能解决你的问题,请参考以下文章

多态的绑定机制

Java类加载器

ReactDOM.render

Java中创建对象初始化过程的理解

在内存中创建了多少个字符串?

这是对在 Java 中创建新对象的过程的正确描述吗?