【问题标题】:Understanding const reference in assignment when constructing object在构造对象时理解赋值中的 const 引用
【发布时间】:2022-01-18 09:07:20
【问题描述】:

今天我看到了这段代码,我想知道在创建新对象的赋值中这个 const 引用到底是做什么的。 (我不知道如何命名这种作业。)

std::string const& p = s.c_str(); // s is a std::string

我知道像 std::string const& p = s; 这样的东西会创建一个引用 ps,但在显示的行中,我们正在创建一个新对象(使用来自 std::string::c_str 的原始指针)。

我在Coliru 中创建了一个 MCVE:

#include <iostream>
#include <string>

void foo(std::string const& s)
{
    std::string const& p = s.c_str(); // << here
    
    std::cout << s << " " << p << " " << &s << " " << &p << std::endl;
}

int main()
{
    foo("hello");
}

而且,正如预期的那样,输出显示创建了一个新对象:

hello hello 0x7ffdd54ef9a0 0x7ffdd54ef950

所以,我的问题是:这真的是在做我看不到的事情吗?代码中是否有任何问题(如悬空引用)?

【问题讨论】:

标签: c++ c++14 variable-assignment const-reference


【解决方案1】:

std::string::c_str's documentation,它返回

指向一个数组的指针,该数组包含一个以 null 结尾的字符序列(即 C 字符串),表示字符串对象的当前值。即const char*

所以当你写的时候:

std::string const& p = s.c_str();

在上述语句中,右侧返回的const char*用于使用@987654322创建std::string类型的临时对象@ 将const char* 作为参数。

接下来,左侧上的左值引用p 绑定到该临时对象。这样做,临时的生命周期延长

要回答您的最后一个问题,您的程序中没有悬空引用。

【讨论】:

  • 是的,这也是我理解的,但是不知道临时对象的引用发生了什么,如果它产生了内存泄漏,等等。
  • @cbuchart 没有内存泄漏。如我的回答末尾所述,临时的生命周期已延长。
  • 如果不延长生命周期,问题将是悬空引用,但仍然没有内存泄漏。
  • @Jarod42 正确。
  • 你说得对,我已经用这个失误更新了问题
【解决方案2】:

其实这个结构

std::string const& p = s.c_str();

没有本质区别
std::string const p( s.c_str() );

但更令人困惑。

至于这条语句的输出

std::cout << s << " " << p << " " << &s << " " << &p << std::endl;

然后输出两个不同的地址。第一个是参数s的地址,第二个是这个声明中创建的std::string类型的临时对象的地址

std::string const& p = s.c_str();

通过转换构造函数

basic_string(const charT* s, const Allocator& a = Allocator());

【讨论】:

  • “更令人困惑” 是有偏见的 ;-) 另一方面,它的优点是确保不会发生 额外 副本(例如,如果该方法已经返回一个 const 引用,而不是一个临时引用,尤其是与 auto 一起使用时。
  • 或者更好std::string const&amp;&amp; ptemp( s.c_str() ); std::string const&amp; p = ptemp;
猜你喜欢
  • 1970-01-01
  • 2015-08-18
  • 2017-06-17
  • 2017-05-07
  • 2012-02-03
  • 2021-11-07
  • 2017-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多