const成员函数的语义是什么? [英] What are the semantics of a const member function?

查看:114
本文介绍了const成员函数的语义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道函数不允许改变对象的状态,但我想我读了一些地方,编译器允许假设如果函数使用相同的参数调用,它将返回相同的值,从而可以重用缓存的值(如果可用)。例如

 类对象
{
int get_value(int n)const
{
...
}

...


对象x;

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

那么编译器可以优化第二次调用,并使用寄存器中的值,这是真的吗?

>解决方案

const 是关于程序语义,而不是关于实现细节。当它不改变对象的可见状态时,你应该标记一个成员函数 const ,并且应该可以在一个对象本身 const 。在 X const 成员函数中, this $ c> X const * :指向常量 X 的对象。因此,所有成员变量在成员函数( mutable 除外)中有效地 const 。如果你有一个 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 //我们想要获取一个const对象的数据
{
boost :: lock_guard< boost :: mutex> lk(m); // this requires m to be non-const
return data;
}
};

如果用指针而不是直接保存数据(包括智能指针,如 std :: auto_ptr boost :: shared_ptr ),则指针变为 const 一个 const 成员函数,但不是指向的数据,所以你可以修改指向的数据。



至于缓存:一般编译器不能这样做,因为状态可能会在调用之间更改(特别是在我的多线程示例与互斥体)。然而,如果定义是内联的,那么编译器可以将代码拉入调用函数并优化它可以看到的内容。这可能会导致 只被调用一次。



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


I understand that the function is not allowed to change the state of the object, but I thought I read somewhere that the compiler was allowed to assume that if the function was called with the same arguments, it would return the same value and thus could reuse a cached value if it was available. e.g.

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

...


object x;

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

then the compiler could optimize the second call away and either use the value in a register or simply do b = a;

Is this true?

解决方案

const is about program semantics and not about implementation details. You should mark a member function const when it does not change the visible state of the object, and should be callable on an object that is itself const. Within a const member function on a class X, the type of this is X const *: pointer to constant X object. Thus all member variables are effectively const within that member function (except mutable ones). If you have a const object, you can only call const member functions on it.

You can use mutable to indicate that a member variable may change even within a const member function. This is typically used to identify variables used for caching results, or for variables that don't affect the actual observable state such as mutexes (you still need to lock the mutex in the const member functions) or use counters.

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;
    }
};

If you hold the data by pointer rather than directly (including smart pointers such as std::auto_ptr or boost::shared_ptr) then the pointer becomes const in a const member function, but not the pointed-to data, so you can modify the pointed-to data.

As for caching: in general the compiler cannot do this because the state might change between calls (especially in my multi-threaded example with the mutex). However, if the definition is inline then the compiler can pull the code into the calling function and optimize what it can see there. This might result in the function effectively only being called once.

The next version of the C++ Standard (C++0x) will have a new keyword constexpr. Functions tagged constexpr return a constant value, so the results can be cached. There are limits on what you can do in such a function (in order that the compiler can verify this fact).

这篇关于const成员函数的语义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆