繁体   English   中英

C++ 临时变量生命周期?

[英]C++ temporary variable lifetime?

我知道这在 C++ 中是有效的,因为来自std::string("xxx")临时性一直存在到它出现的完整表达式的末尾。

printf("%s\n", std::string("xxx").c_str());

这也有效:

std::string f1() {
    return std::string("xxx");
}

void g1() {
    printf("%s\n", f1().c_str());
}

但这是有效的吗? 如果不是,为什么?

const char* f2() {
    return std::string("xxx").c_str();
}

void g2() {
    printf("%s\n", f2());
    // or: std::string x = f2(); // is this valid?
}

当函数返回时, f2的临时std::string被销毁。 char*将悬空。

编辑:作为对评论的回应, std::string x = f2()也无效。 从悬空指针初始化std::string仍然很糟糕。

完全相同的规则适用。 f2中创建std::string的完整表达式是

std::string("xxx").c_str()

以及从中构造返回值。

执行此表达式并执行返回值的构造后,临时std::string("xxx")将被销毁。 由于临时std::string销毁使得从.c_str()获得并复制到返回值中的const char*无效,因此不能以任何方式使用该函数的返回值。

对于f1 ,同样适用(有关临时物化和复制省略的详细信息,尤其是在 C++17 中,旁白)。 临时std::string在构造返回值后被销毁。 但在这种情况下,这不是问题,因为返回值不是指向已销毁对象的指针,而是一个独立的std::string对象本身。 这个std::string对象将一直存在到出现对f1的调用的完整表达式的结尾,即直到

printf("%s\n", f1().c_str())

以下也可以:

std::string f3() {
    return std::string("xxx").c_str();
}

同样,在返回值中创建了一个新的std::string ,它将一直存在到调用f3的完整表达式结束。


实际上,对于f1 ,因为std::string("xxx"); 已经是std::string类型的纯右值,将应用复制省略,因此实际上只有一个临时对象,即f1的返回值。 中间临时将被消除,返回值直接由"xxx"构造。 从 C++17 开始这是强制性的,并且在 C++17 之前是允许和常见的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM