关于C#:const成员函数的语义是什么?

关于C#:const成员函数的语义是什么?

What are the semantics of a const member function?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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成员函数中)或使用计数器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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标准(C 0x)将具有新的关键字constexpr。标记为constexpr的函数返回常数,因此可以将结果缓存。在此函数中可以执行的操作受到限制(以便编译器可以验证此事实)。


在成员变量上可变的关键字允许const函数更改当前对象的状态。

而且不,它不缓存数据(至少不是所有调用),因为以下代码是随时间变化的有效const函数:

1
int something() const { return m_pSomeObject->NextValue(); }

请注意,指针可以是const,尽管所指向的对象不是const,因此对SomeObject的NextValue的调用可能会或可能不会更改其自身的内部状态。这会使函数每次调用时都返回不同的值。

但是,我无法回答编译器如何使用const方法。我听说它可以优化某些功能,尽管我必须对其进行


不。

const方法是一种不会更改对象状态(即其字段)的方法,但是您不能假设给定相同的输入,就可以确定const方法的返回值。换句话说,const关键字并不意味着该功能是一对一的。例如,返回当前时间的方法是const方法,但是其返回值在两次调用之间改变。


在这种情况下,const成员函数意味着this也被视为const指针。实际上,这意味着您不允许在const成员函数内修改this的状态。

对于无副作用的函数(例如,您尝试的是要实现),GCC具有一个名为pure的\\"功能属性\\\\"(您可以通过说__attribute__((pure))来使用它):http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes。 html


成员函数上的const关键字将此参数标记为常量。该函数仍然可以静音全局数据(因此不能被缓存),但是不能静音对象数据(允许调用const对象)。


还允许使用

const方法修改静态本地。例如,以下代码是完全合法的(重复调用bar()将返回递增值-而不是缓存的0):

1
2
3
4
5
6
7
8
9
class Foo
{
public:
    int bar() const
    {
        static int x = 0;
        return x++;
    }
};

Corey是正确的,但请记住,任何标记为可变的成员变量都可以在const成员函数中进行修改。

这也意味着可以从其他const函数或通过调用这些函数其他const引用。

编辑:该死,被9秒殴打...。9! :)


除了成员函数可以修改全局数据这一事实之外,成员函数还可以修改相关对象的显式声明的可变成员。


我对此表示怀疑,该函数是否仍可以调用一个全局函数,该函数可以更改世界的状态并且不违反const。


推荐阅读

    excel怎么用乘法函数

    excel怎么用乘法函数,乘法,函数,哪个,excel乘法函数怎么用?1、首先用鼠标选中要计算的单元格。2、然后选中单元格后点击左上方工具栏的fx公

    excel中乘法函数是什么?

    excel中乘法函数是什么?,乘法,函数,什么,打开表格,在C1单元格中输入“=A1*B1”乘法公式。以此类推到多个单元。1、A1*B1=C1的Excel乘法公式

    标准差excel用什么函数?

    标准差excel用什么函数?,函数,标准,什么,在数据单元格的下方输入l标准差公式函数公式“=STDEVPA(C2:C6)”。按下回车,求出标准公差值。详细

    excel常用函数都有哪些?

    excel常用函数都有哪些?,函数,哪些,常用,1、SUM函数:SUM函数的作用是求和。函数公式为=sum()例如:统计一个单元格区域:=sum(A1:A10)  统计多个