【问题标题】:What does `const` behind a function header mean? [duplicate]函数头后面的`const`是什么意思? [复制]
【发布时间】:2012-03-20 16:32:01
【问题描述】:

有一个class A,它具有以下operator() 实现:

void A::operator()(...parameters...) const 
{
    // operator body
}

const 是什么意思?

【问题讨论】:

    标签: c++ syntax constants


    【解决方案1】:

    C++ 中的方法可以像上面的例子一样标记为const,表示该函数不修改实例。为了强制执行这一点,this 指针在方法中属于 const A* const 类型。

    通常,方法中的this 指针是A* const,表示我们无法更改this 指向的内容。也就是说,我们不能做this = new A()

    但是当类型为const A* const 时,我们也无法更改任何属性。

    【讨论】:

    • 你不能改变this的原因是因为它不是一个lvalue表达式,而不是因为它有一个它没有的const限定类型.事实上,您不能拥有const 限定的非类类型的右值
    • @CharlesBailey:你从哪里找到这些信息的?我咨询过的消息来源解释说指针的类型是const A* constpublib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/…msdn.microsoft.com/en-us/library/ytk2ae82.aspx
    • 在标准中,第 9 章中关于 this 的部分和第 3 章中关于值类别的部分。
    • @CharlesBailey:这当然是最权威的来源。感谢您更正我提供的信息。对于其他感兴趣的人,请参阅第 155 页 cs.technion.ac.il/users/yechiel/CS/C++draft/ISO-CPP-body.pdf。谢谢查尔斯!
    • 但是,为了混淆问题,const成员函数可以修改显式标记为mutable的成员。
    【解决方案2】:

    该方法使用this作为const A*,然后只能调用其他const方法。

    请参阅 CPP 常见问题解答的 this 条目。

    【讨论】:

    • 小挑剔——类型实际上变成了const A* const
    • @Cam:不,类型只是const A*this 是一个 rvalue,这就是为什么你不能分配给它或获取它的地址,而不是因为它是 const
    【解决方案3】:

    正如已经充分描述的,这意味着该方法不会修改对象的可观察状态。而且,非常重要的是,这意味着可以在 const 对象、指针或引用上调用该方法——非 const 方法不能。即:

    class A
    {
    public:
        void Method1() const
        {
        }
    
        void Method2()
        {
        }
    };
    
    int main( int /*argc*/, char * /*argv*/ )
    {
    
        const A a;
        a.Method1(); //ok.
        a.Method2(); //compiler error!
    
        return 0;
    }
    

    【讨论】:

    • 请不要假设它不会修改对象,只有可见状态保持不变。
    • 也已经充分说明。 :) 到目前为止,我是唯一一个指出只能在 const 对象上调用 const 方法的人。我的赞成票呢!?!?
    • 实际上,你有我的赞成票,但也有反对票,因为 const 方法可能会改变对象。但它们不会改变外部可见的状态。
    • 在添加重要部分之前,我认为很明显我正在总结上面的答案。我现在已经把它擦亮了。尽管如此,现在我必须找到反对者并永远在互联网上跟踪他们!我在哪里可以找到时间!?
    • 您下次想使用“@”,所以我会收到通知;)我的(虚拟)反对票消失了,总和为 +1。顺便说一句,你没有收到任何真正的反对票。
    【解决方案4】:

    const 关键字指定该函数是“只读”函数,不会修改调用它的对象。

    【讨论】:

      【解决方案5】:

      表示调用操作符不会改变对象的状态。

      【讨论】:

      • 不一定,感谢const_castmutable
      • @dan04:好的,所以它的意思是“不会改变对象的状态......除非有人作弊!” :P
      • @dan04:通过const_cast 改变常量值会产生未定义的行为。
      • @piokuc:也许将其细化为“可观察状态”。
      • @piokuc:示例:您有一个四叉树类。在引擎盖下,四叉树是惰性构建的,即按需构建;这种懒惰对班级的用户是隐藏的。现在,对该四叉树的查询方法应该是const,因为查询四叉树预计不会改变四叉树。如何在不违反 C++ 规则的情况下实现 const 正确性和惰性?使用mutable。现在您有了一个对于用户来说看起来是 const 的四叉树,但您知道在底层,还有很多变化。
      【解决方案6】:

      const 成员函数承诺不会改变对象的可观察状态。

      在底层,它可能仍会改变状态,例如的mutable 成员。但是,mutable 成员永远不应该从类接口之外的任何地方可见,即您永远不应该试图对客户端代码撒谎,因为客户端代码可能有效地期望 const 函数不会调整对象的外壳。将mutable 视为一种优化工具(例如,用于缓存和记忆)。


      可变性示例:

      你有一个四叉树类。在引擎盖下,四叉树是惰性构建的,即按需构建;这种懒惰对班级的用户是隐藏的。现在,对该四叉树的查询方法应该是const,因为查询四叉树预计不会改变四叉树。如何在不违反 C++ 规则的情况下实现 const 正确性和惰性?使用mutable。现在你有一个对于用户来说看起来是 const 的四叉树,但你知道在底层,还有很多变化:

      class Quadtree {
      public:
          Quadtree (int depth);
          Foo query (Bar which) const;
      
      private:
          mutable Node node_;
      };
      

      【讨论】:

        猜你喜欢
        • 2015-09-29
        • 1970-01-01
        • 2020-04-07
        • 2011-05-02
        • 2011-03-09
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多