【问题标题】:What's the difference between these two local variables?这两个局部变量有什么区别?
【发布时间】:2011-02-04 17:27:57
【问题描述】:
const std::string  s1("foo");
const std::string& s2("foo");

不确定它们有何不同,但我看到了两种用法的证据。有什么想法吗?

【问题讨论】:

  • 这个问题究竟是关于什么的?你从来没有听说过引用?或者您实际上知道什么是引用,但从未见过以这种方式初始化的引用?在前一种情况下,您需要先阅读一些有关 C++ 的书。尝试通过询问不熟悉的语法来学习语言的基本特征并不是一种有效的方法。
  • @AndreyT 我对这门语言比较陌生,但我想知道这两个实例之间存在哪些微妙之处。至少根据我的经验,我没有遇到过第二个例子,我想知道它的用途。
  • 无用的琐事:当前的 C++ 语言标准中存在一个缺陷,即声明只有对象可以是变量。因为s2 是一个引用,而不是一个对象,所以它在技术上不是一个变量。此缺陷已在下一个即将发布的 C++ 语言标准版本 C++0x 中得到修复。
  • @JamesMcNellis:这表明应用标准语言通常是无益的。 :)
  • @Fred:我同意。我确实在它前面加上了“无用的琐事”,因为那真的很没用。

标签: c++ variables reference constants local


【解决方案1】:
const std::string s1("foo");

这将一个名为 std::string 的对象声明为局部变量。

const std::string& s1("foo");

这声明了对 std::string 对象的 const 引用。使用内容 "foo" 创建一个未命名的临时 std::string 对象,并且引用绑定到该临时对象。临时对象将一直存在,直到引用超出范围。

在这种特殊情况下,两者之间没有明显的区别:在这两种情况下,您最终都会得到一个 std::string,它可以通过名称 s1 访问,并且在 s1 退出时将被销毁范围。

但是,在某些情况下,情况有所不同。例如,考虑一个通过引用返回的函数:

const std::string& get_reference_to_string();

如果用调用该函数的结果来初始化s1,则有以下区别:

const std::string s1(get_reference_to_string());
const std::string& s1(get_reference_to_string());

在第一种情况下,复制引用的字符串并用于初始化s1。在第二种情况下,s1 简单地绑定到返回的引用所指的std::string:没有复制。

【讨论】:

    【解决方案2】:

    它们在含义上是相同的,因为常量引用可以绑定到临时变量以及从 char* 隐式转换的字符串。

    为了清晰和可读性,首选非参考。

    【讨论】:

    • 弗雷德,你是一台机器!你知道有什么资源可以更深入地研究这个吗?想了解更多关于幕后发生的事情。
    • 第二个示例是否会创建对该对象的长期引用,因此如果您将它传递到其他保留引用的地方,它将保持有效,而不是第一个示例仅具有本地范围?跨度>
    • @chriskirk:不,除了复制省略的实现细节(由于所有体面的 C++ 编译器的作者的辛勤努力,可以忽略它),它们的含义是相同的。如果您将源(“foo”)更改为其他内容(如 James 的回答)或将类型更改为其他内容(如我在回答中试图说的),则含义可能会改变。
    • 我不明白为什么不存在或不可访问的复制构造函数会导致引用初始化无效:没有复制。
    • @JamesMcNellis:你是对的;我对复制初始化(C++03 §8.5p12)感到困惑,但它适用于非引用形式。
    【解决方案3】:

    第一个实例创建一个常量字符串变量,初始化为保存“foo”。第二个创建一个对字符串的常量引用,然后将该常量引用初始化为指向一个临时字符串,该字符串被初始化为保存“foo”。

    【讨论】:

      【解决方案4】:

      const std::string s1("foo"); 在堆栈上创建一个std::string 对象,并使用const char* 字符串“foo”对其进行初始化。另一方面,const std::string& s1("foo") 是对隐式构造的 std::stringconst 引用

      【讨论】:

      • 这是一个坏主意,因为它读起来有点混乱。但除此之外,它是完全有效的代码,并且不会创建悬空引用。
      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 2017-03-27
      • 2015-11-23
      • 2021-11-07
      • 1970-01-01
      相关资源
      最近更新 更多