【问题标题】:Why when a constructor has a reference to string does not printed correctly?为什么当构造函数引用字符串时不能正确打印?
【发布时间】:2020-07-27 03:30:23
【问题描述】:

我有下面的代码,当它的析构函数被调用时它没有打印出正确的字符串

struct Tracer {

 Tracer( const std::string& name_in)
 : name{ name_in } {
  std::cout << name << " constructed.\n";
 }

~Tracer() {
 std::cout << name << " destructed.\n";
}

private:

const std::string& name;
};

Tracer static_tracer{ "static Tracer" };

int main() {

}

输出: 静态 Tracer 构造。

�1�Q�

但以下代码按预期工作:

Tracer( std::string name_in)
 : name{ std:move(name_in) } {
 std::cout << name << " constructed.\n";
 }

private:
std::string name;

输出: 静态 Tracer 构造。

静态追踪器被破坏。

或者当使用字符串视图或简单的字符串时。

在第一个代码的程序终止期间,我们如何丢失了对字符串的引用?

难道我们不应该使用 move() 释放对字符串的引用,因为它具有构造函数作用域吗?

谢谢!

【问题讨论】:

  • 因为这就是 C++ 的工作方式。构造一个临时对象,存储对临时对象的引用,销毁临时对象;最后尝试取消引用现在的垃圾引用,随之而来的是希拉里。你的 C++ 书应该有很多章节来讨论引用的要点和作用域的生命周期。这是一个很大的主题,无法在 stackoverflow.com 上的一两段中完全解释,所有细节都必须参考您的教科书。
  • 如果您想要std::string,请使用std::string。当您想要引用其他对象时,引用很有用。无意冒犯,但这里的问题是你自己不知道会员指的是什么
  • ...简单地说:const std::string&amp; name; -> const std::string name;
  • 甚至不必是const std::string name;。会员是你自己的。如果你愿意,它可以是非常量的。
  • 请注意,C++ 中的“引用”与 Java(和许多其他语言)等语言中的“引用”不同。

标签: c++ string reference c++17 stdmove


【解决方案1】:

问题是您不能将字符串引用 (std::string const&amp;) 指向const char[14],即"static Tracer"

为了让它工作,C++ 发明了一个临时对象std::string{"static Tracer"}。该对象将一直存在,直到您的构造函数返回,但不再是static_tracer 的构造函数在 main 开始之前返回。显然析构函数也在构造函数返回后运行。

【讨论】:

  • 但是它被声明为 const 引用...而且在 main 之后调用析构函数,特别是在整个程序终止之后,因为它被初始化为全局而不是在构造函数之后立即
  • @stelios 唯一的 std::string 实例是临时的。有时临时对象通过绑定到 const 引用来延长他们的生命周期(你指的是那个吗?),这里不是这种情况
  • 终身延长在这里无关紧要。它使临时文件与引用一样长,但这里的“引用”将是构造函数参数列表中的const std::string&amp; name_in,而不是 Tracer::name
  • @MSalters 是的,你是对的,我错过了 const std::string& name_in 实际上是一个临时对象的部分,这是成员 name 指向的对象。现在说得通了。我会接受你的回答。谢谢!
  • @stelios:C++ 对某些单词有非常具体的含义。 “对象”就是其中之一。const std::string&amp; name_in 对象的引用,在您的情况下是未命名的临时对象。但是引用本身不是对象。正如您的问题所示, 稍有错误就会导致意想不到的效果,所以我尽量做到准确。
猜你喜欢
  • 2012-09-13
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
  • 2021-03-06
  • 1970-01-01
  • 2016-02-17
相关资源
最近更新 更多