【问题标题】:about const member function [duplicate]关于 const 成员函数 [重复]
【发布时间】:2009-12-27 16:29:16
【问题描述】:

我遇到了两个关于const成员函数的解释

class A{
  public:
  ...
  void f() const {}
  ...
}
  1. 这意味着它只能访问常量成员;
  2. 表示不修改任何成员;

我认为第二个是正确的。但是为什么第一个出来?有什么需要澄清的吗?

谢谢!

【问题讨论】:

标签: c++ constants const-correctness


【解决方案1】:

您可以检查 const 成员函数中的所有类成员值,在某些情况下,您甚至可以更改成员变量的值。第一个解释是不正确的,我不知道它来自哪里。第二种解释是正确的,但有一些例外。

这条规则有一些例外。您还可以在 const 成员函数中更改可变变量,例如像这样声明的成员变量:

mutable float my_rank;

您还可以通过 const_cast'ing 对自己的引用来破坏类中的 const 正确性,如下所示:

Class* self = const_cast<Class*> (this);

虽然在 C++ 中技术上允许,但这通常被认为是糟糕的形式,因为它丢弃了设计中的所有 const 修饰符。除非您确实必须这样做,否则不要这样做,并且如果您发现自己必须这样做很多,这表明您的设计存在问题。 C++ FAQ 很好地涵盖了这一点。

如果您想进一步阅读,这里有两个参考资料:

【讨论】:

    【解决方案2】:

    简单来说,在 const 函数中你不能改变对象的状态。

    在 const 函数中,此指针的行为类似于 const 指向 const 数据的指针,而在 非 const 函数中,它的行为类似于 指向数据的常量指针

    void foo() const  --> const ClassName * const this (so you can't alter data)
    
    void foo() --> ClassName * const this (so you can alter data)
    

    就 const 数据成员而言,您可以从任何成员函数访问(读取)它,无论其是否为 const。

    正如 James Thompson 所展示的,如果您愿意,您甚至可以通过移除 constness 来更改对象的状态。

    class Bar
    {
        int bar;
        public:
         void foo() const
         {
            this->bar = 0; //flashes error 
    
            Bar * const thisClass = const_cast<Bar * const>(this);
            thisClass->bar = 0;  
         }
    };
    

    在 const 函数中也可以更改可变数据成员。

    【讨论】:

      【解决方案3】:

      他们都是正确的。

      const 成员函数不能改变对象的状态

      • 这意味着它可以读取(但不能修改)所有成员变量。
      • 这也意味着它只能调用其他的 const 成员函数
        其他保证不改变对象状态的方法。

      以上 James 还提到了可变成员。
      所以我也应该在这里介绍这些。

      可变成员变量是不属于对象状态的变量(编译器不认为它是对象状态的一部分)。你也应该这样对待它。任何保存对象状态信息的成员变量都应该标记为可变的。您应该只使用它来保存可以从对象状态重建的临时信息。

      一个简单的例子是日期时间对象。其中对象具有将数据/时间转换为可读字符串格式的方法。为了提高效率,该字符串可能会缓存在对象中的可变成员中(这样您就不需要重复构建字符串)。但字符串不是对象状态的一部分(因为它可以由其他成员构建)。

      James 还提到上面使用 const_cast 来消除 constness。

      除非在非常特殊的情况下,您知道对象 永远不可能 const 这样做通常被认为是一个坏主意。因为它直接导致未定义的行为。如果您发现自己需要抛弃 constness,那么您的程序中的设计就出现了一些非常错误的问题。

      事实上,我只能想到一种正常发生的情况。然后我不愿意在没有先去研究以确保我看起来不傻的情况下将其提交给代码。

      【讨论】:

      • 我认为您对第一个问题的阅读方式与我不同。提议的定义是“它只能访问常量成员”。一个 const 成员函数可以访问非常量成员,只要它不改变修改它们的状态,所以定义是不正确的。
      • @詹姆斯。请让你的陈述更清楚。 const 方法可以读取任何成员变量。但只能调用 const 成员方法。我认为很明显,最初的问题只是混淆了一些小细节。
      • 不用担心,虽然给出了2个具体的例子..将拿出所有的cmets并开始支持媒体渠道展示琐碎的观察。谁知道呢,也许我会开始看到每辆车都有一条专用车道,而不是一条路。
      • @rama:你在说什么?
      【解决方案4】:

      我认为经过一些澄清后的案例 1 可能涉及当您拥有 A 类型的 const 对象时的情况。在这种情况下,您只能调用其声明为 const 的成员函数,如 f() 在这种情况下。因此,根据您的帖子,您必须假设“它”是 const A 类型的对象上成员函数的调用者。也许您应该在考虑到这个假设的情况下查看您发现的定义。

      【讨论】:

        猜你喜欢
        • 2020-04-02
        • 2011-06-04
        • 2016-08-17
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 2021-09-11
        • 2014-05-25
        • 1970-01-01
        相关资源
        最近更新 更多