c++ - const 成员函数的语义是什么?

标签 c++ methods constants

我知道该函数不允许更改对象的状态,但我想我在某处读到允许编译器假设如果使用相同的参数调用该函数,它将返回相同的值并且因此可以重用缓存的值(如果可用)。例如

class object
{
    int get_value(int n) const
    {
        ...
    }

...


object x;

int a = x.get_value(1);
    ...
int b = x.get_value(1);

然后编译器可以优化第二次调用并使用寄存器中的值或简单地执行 b = a;

这是真的吗?

最佳答案

const 是关于程序语义而不是关于实现细节。当成员函数 const 不改变对象的可见状态时,您应该标记它,并且应该可以在本身为 const 的对象上调用。在类 Xconst 成员函数中,this 的类型是 X const *:指向常量的指针X 对象。因此,所有成员变量实际上都是该成员函数中的 const(mutable 除外)。如果你有一个 const 对象,你只能在它上面调用 const 成员函数。

您可以使用 mutable 来指示成员变量即使在 const 成员函数内也可能发生变化。这通常用于识别用于缓存结果的变量,或者用于不影响实际可观察​​状态的变量,例如互斥锁(您仍然需要在 const 成员函数中锁定互斥锁)或使用计数器。

class X
{
    int data;
    mutable boost::mutex m;
public:
    void set_data(int i)
    {
        boost::lock_guard<boost::mutex> lk(m);
        data=i;
    }
    int get_data() const // we want to be able to get the data on a const object
    {
        boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
        return data;
    }
};

如果您通过指针而不是直接保存数据(包括智能指针,例如 std::auto_ptrboost::shared_ptr),则指针变为 const 在一个 const 成员函数中,而不是指向的数据,所以你可以修改指向的数据。

至于缓存:通常编译器不能这样做,因为状态可能会在调用之间发生变化(尤其是在我使用互斥锁的多线程示例中)。但是,如果定义是内联的,那么编译器可以将代码拉入调用函数并优化它在那里可以看到的内容。这可能会导致函数有效地只被调用一次。

C++ Standard (C++0x) 的下一个版本将有一个新的关键字 constexpr。标记为 constexpr 的函数返回一个常量值,因此可以缓存结果。在这样的函数中你可以做的事情是有限制的(以便编译器可以验证这个事实)。

关于c++ - const 成员函数的语义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/98705/

相关文章:

c++ - 换行不适用于 C++ 中的文件?

c++ - 是否有任何 API 可以在 Windows 中获取路径 "C:\Documents and Settings"?

c++ - _ftime/Windows 内部时间如何工作?

c++ - 显式指定方法/构造函数是否意味着不能隐式调用它?

java - 强制子类在抽象 java 类中包含常量

基于 Rails 变量的 Javascript 条件

c++ - 为什么我需要为传递给 Y 组合器的函数指定返回值

jquery - 将 css 属性数组传递给 .css 方法

扩展/方法中的 C# Linq

php - 使用define()存储数据库连接详细信息是好是坏?