【问题标题】:C++ const semantics for a referenceC++ const 语义供参考
【发布时间】:2012-01-29 11:13:15
【问题描述】:

如果代码中有类似下面的内容:

func(const base& obj)

const 语义是什么意思?什么是不变的? obj 是 const reference to a non-const object 还是 non-const reference to a const object

【问题讨论】:

    标签: c++ reference constants semantics


    【解决方案1】:

    正如其他答案所说,obj 是对const base 对象的引用。但是,这并不意味着它所引用的对象恰好具有base 类型,或者它所引用的对象是const,只是func 不能修改obj 通过那个参考。例如:

    struct derived : base { ... };
    derived d;
    func(d);
    

    是合法的,并且:

    bool other_func(const base& b, other_object& o) {
       base b_copy = b;
       o.foo();
       return b_copy == b;
    }
    

    如果o 具有对b(或其中的某些内容)的内部非常量引用并且o.foo() 修改b,则可能返回false。这对诸如

    之类的功能具有实际意义
    std::string::operator=(const std::string& other);
    

    幼稚的实现可能会对my_str = my_str 做错事。

    【讨论】:

      【解决方案2】:

      obj 是对 const base 的引用,因此这意味着您不允许更改引用的对象。可以写成

      func(const base& obj)
      

      func(base const & obj)
      

      使用从右到左的规则来读取这样的声明类型,对于这个简单的例子,只需从右边读取它。更多信息在这里:

      http://www.codeproject.com/KB/cpp/complex_declarations.aspx

      【讨论】:

      • 另外,甚至认为:'base const & obj' 起初可能看起来很奇怪,它更容易阅读,你只需按照所写的从右边开始:obj 是对 const base 的引用
      【解决方案3】:

      如果没有 const,您将无法向该函数发送 const 对象。所以添加 const 总是积极的。特别是当您为许多用户创建功能时。经典示例是 setter 函数。

      x->setXsth(sth& obj)              // works only with  non-const object. 
      x->setXsth(const sth& obj)        //works with  const object and non-const.
      

      【讨论】:

        【解决方案4】:

        有些不请自来的答案/观点:const 修饰符修改其左侧的任何内容,除了您正在使用的一种构造(在这种情况下,它会立即修改任何内容正确的)。我发现总是将 const 放在我要修改的任何内容的右侧更容易,并从右到左阅读语句。也许这不是最好的做事方式,但它可以帮助我保持直截了当。

        例子:

        // these two statements are equivalent
        const int x = 5; // special case usage
        int const x = 5;
        
        // using the LHS syntax makes multiple consts easier to understand
        int const y = 6;
        int const * const x = &y; // x is a const pointer to const int
        
        // const can apply to pointers but not to references
        int const & const z = y; // redundant, references are always const
        

        【讨论】:

          【解决方案5】:

          obj 是在参数中传递给func() 的对象的常量引用(无论对象是 const 还是非 const)

          如果你写:func(B);

          这意味着你不能在函数func()中改变B的内容

          (其中func(const base& obj)

          【讨论】:

          • 感谢评论,不知道... :) 我写了正确和有用的答案
          • 我没有投反对票,但任何投反对票的人都可能反对“对对象的 const 引用”。大多数人会说“引用 const 对象”。
          • @Oli Charlesworth:我理解你的回答。但是这种引用类型通常被称为:常量引用。
          • 但是没有“非常量引用”这样的东西,所以只需要说“引用”。
          • @eharvest:我们称这些为“对 T 的引用”和“对 const T 的引用”。
          【解决方案6】:

          它被称为常量引用。您对已传递的数据具有“引用访问权限”,但您无法对其进行修改。

          【讨论】:

            【解决方案7】:

            没有“非常量”引用这样的东西,也就是说,引用总是绑定到同一个对象,并且没有办法改变它。 "const type&" 表示引用 const 类型。

            【讨论】:

            • 所以const base &obj也可以用作base const &obj?
            • 那是错误的。根据标准,存在非常量引用。
            • 也错了:“const type&”表示引用 const 类型。根据标准,这是对 const 或非 const 对象的 const 引用。
            • @LinuxPenseur: "const base&" 和 "base const&" 是同一类型。
            • @eharvest:存在对非常量对象的引用。 C++ 中不存在本身可变的引用(即可以更改它们引用的对象)。
            【解决方案8】:

            obj 是一个const 对象的引用

            没有“非常量引用”这样的东西,因为引用在创建后无法更改为引用其他内容。

            【讨论】:

            • 所以只有一个const对象可以作为func的参数传递?
            • 任何对象(无论是否为 const)都可以作为参数传递。但是,在函数func() 中,对象的使用仅限于那些对const 对象有效的操作。所以调用者知道调用func(obj)不会改变obj
            • 谢谢。这对像我这样的初学者非常有用:)
            • 有一个常量引用:不能修改引用的对象。并且对对象的引用可以改变被引用对象的内容。所以,有
            • @Greg Hewgill:您的答案是错误的:根据标准存在“非常量引用”。你的解释是错误的。 “非常量引用”是指能够改变被引用对象内容的引用。它符合标准。检查一下。
            猜你喜欢
            • 1970-01-01
            • 2021-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-14
            • 2011-09-03
            • 1970-01-01
            • 2018-10-04
            相关资源
            最近更新 更多