【问题标题】:What is meant with "const" at end of function declaration? [duplicate]函数声明末尾的“const”是什么意思? [复制]
【发布时间】:2011-03-09 15:19:12
【问题描述】:

我有一本书,上面写着:

class Foo 
{
public:
    int Bar(int random_arg) const
    {
        // code
    }
};

什么意思?

【问题讨论】:

  • 它将this 的类型从Foo* const 更改为const Foo* const。这会产生后果。
  • 我不明白您的编辑。你到底想知道什么?如果声明两个 Foo 类型的变量会创建多个 Bar 的函数实例?
  • @inflagranti:是的,这正是我想知道的。
  • 那么答案是否定的。你为什么认为会是这样?
  • @aPoC 函数(或此处的方法)仅在“内存中”存在一次(是否为static,没关系)。他们获得了一个隐藏参数this,它是一个指向调用实例的指针。

标签: c++ constants


【解决方案1】:

在函数声明后用关键字const 表示的“const 函数”会使此类函数更改类的成员变量成为编译器错误。但是,在函数内部读取类变量是可以的,但是在函数内部写入会产生编译器错误。

考虑这种“const 函数”的另一种方法是将类函数视为采用隐式 this 指针的普通函数。因此,int Foo::Bar(int random_arg) 方法(末尾没有 const)会产生像 int Foo_Bar(Foo* this, int random_arg) 这样的函数,而像 Foo f; f.Bar(4) 这样的调用将在内部对应于像 Foo f; Foo_Bar(&f, 4) 这样的东西。现在在末尾添加 const (int Foo::Bar(int random_arg) const) 可以理解为带有 const this 指针的声明:int Foo_Bar(const Foo* this, int random_arg)。由于这种情况下this 的类型是 const,所以不能修改成员变量。

可以放宽不允许函数写入类的任何变量的“const 函数”限制。为了让某些变量即使在函数被标记为“const 函数”时仍可写,这些类变量用关键字mutable 标记。因此,如果一个类变量被标记为可变,并且一个“const 函数”写入这个变量,那么代码将编译干净并且变量可以改变。 (C++11)

像往常一样,在处理const 关键字时,在 C++ 语句中更改 const 关键字的位置具有完全不同的含义。 const 的上述用法仅适用于在括号后的函数声明末尾添加const 时。

const 是 C++ 中一个被过度使用的限定符:语法和排序通常与指针结合起来并不简单。一些关于const 正确性和const 关键字的阅读:

Const correctness

The C++ 'const' Declaration: Why & How

【讨论】:

  • @ereOn,如果你喜欢 mutable,你可能会喜欢这个。 “可变”最常见的用例是作为互斥锁的修饰符来控制对类实例的访问。仅仅因为您承诺不修改实例,并不意味着您从中读取的内容不会被持有非 const 引用的其他人修改。
  • @Janick,我已经自学了一两年的 c++,从来没有见过任何书籍包含这样的解释,我觉得它真的很有帮助。我应该阅读什么类型的书来学习这些隐含 this 指针的东西。
  • @Steven:我认为最有帮助的事情可能是实际阅读一本 C 书籍以及如何用纯 C 实现一些类似 OO 的东西。从中更容易了解 C++ 原生 OO 是如何实现的功能映射到 C 中更底层的结构,并最终向下映射到机器。
  • 还有2点需要注意:1)静态数据成员仍然可以修改。 2) 这里检查的是按位常量,这意味着调用函数的对象的内存是逐位检查的,不应对其进行任何更改。这进一步告诉我们,如果有一个 int* 数据​​成员,那么这个指针包含在对象内存中的地址不能改变,但该位置不属于对象内存的值可以改变。
  • @LukasThiersch,如果 const 函数调用 non-const 函数改变值,编译器会抛出 error
【解决方案2】:

类似于this 问题。

本质上意味着Bar方法不会修改Foo的非mutable成员变量。

【讨论】:

    【解决方案3】:

    函数不能通过你给它的指针/引用来改变它的参数。

    每当我需要考虑它时,我都会去这个页面:

    http://www.parashift.com/c++-faq-lite/const-correctness.html

    我相信 Meyers 的“更有效的 C++”中也有很好的篇章。

    【讨论】:

      【解决方案4】:

      考虑两个类类型变量:

      class Boo { ... };
      
      Boo b0;       // mutable object
      const Boo b1; // non-mutable object
      

      现在您可以在b0 上调用Boo任何 成员函数,但只能在b1 上调用const 限定的成员函数。

      【讨论】:

        【解决方案5】:

        我总是觉得在概念上更容易想到你正在使 this 指针变为 const(这几乎就是它的作用)。

        【讨论】:

        • 其实不是this指针本身就是const,而是它所指向的,即*this;)
        【解决方案6】:

        Bar 保证不会更改正在调用它的对象。例如,请参阅 C++ FAQ 中的section about const correctness

        【讨论】:

        • 别忘了mutable关键字。
        猜你喜欢
        • 1970-01-01
        • 2011-05-02
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多