可以被const函數修改的非const變量----mutabel

原問是mutable variables and const functions
mutable variables can be altered by const functions. But what is the reason of declaring a function as const and then some variables as mutable and not just use normal variables and non const functions?
提到:mutable變量可以被常函數修改。但是聲明常函數,使用mutable變量而不用普通變量非-常函數的原因是什麼?

This keyword can only be applied to non-static and non-const data members of a class. If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function.
此關鍵字只能應用於類的非靜態和非常量數據成員。 如果數據成員被聲明爲可變的,那麼從const成員函數向這個數據成員賦值是合法的。

1.以下聲明是相同的(The following declarations are identical):

const char* p;
char const* p;

Both declare a pointer to a constant character. The second is slightly better in the sense that the declaration can be read from right-to-left: p是一個指向const char的指針.(“p is a pointer to a const char”). Read as such, it is easy to see that the line *p = ‘c’; will not compile.

2.The following declaration:
char* const p;

聲明p是指向字符的常量指針(declares p to be a constant pointer to a character). That is:
p = "foo"; // Does not compile
*p = 'f'; // Compiles!

3.And thus:
const char* const p;
char const* const p;

均聲明p是一個常量指針指向一個常量字符(both declare p to be a constant pointer to a constant character), and so none of the following lines of code compile:
p = "foo";
*p = 'f';

4.現在放入另一個指針(Now throw another pointer into the mix):
const char** p;
char const** p;

These are equivalent 等價的 and declare p to be a pointer to a pointer to a constant character. That is:
p = ptr-to-ptr-to-char; // Compiles
*p = ptr-to-char; // Compiles
**p = 'f'; // Does not compile

5.Or how about creative placement of const:
char* const* p;

This declares p to be a pointer to a constant pointer to a character.
That is:
p = ptr-to-constptr-to-char; // Compiles
*p = ptr-to-char; // Does not compile
*p = constptr-to-char; // Does not compile
**p = 'f'; // Compiles

6.和廣受歡迎的(And the ever-popular):

char** const p;

Which declares p to be a constant pointer to a pointer to a character. Or:
p = ptr-to-ptr-to-char; // Does not compile
p = constptr-to-ptr-to-char; // Does not compile
*p = ptr-to-char; // Compiles
**p = 'f'; // Compiles

7.And now we get just plain const happy:
const char* const* p;

p is a pointer to a constant pointer to a constant character. The only thing you can do with this one (besides remove the code and rewrite) is:
p = ptr-to-constptr-to-constchar;

8.const char** const p;

p is a constant pointer to a pointer to a constant character. The only thing you can do with this is:
*p = ptr-to-constchar;

9.And this beast:
const char* const* const p;

Well, it won’t pass code review since nobody will understand it, but at any rate… We’ve achieved maximum constant-ness with this line. You can’t do anything at all with p, what it points to, what that points to, or what “what that” points to. You can print it. That’s about it.

嗬 - 嗬,樂趣纔剛剛開始(Ho-ho, and the fun is just beginning). Now throw in 引用REFERENCES)!

const char& p;
char const& p;

這兩個都聲明p是一個常量字符的引用。 也就是說,p不能改變。
(These both declare p to be a reference to a constant character. That is,p cannot change.)

char& const p;
const char& const p;
char const& const p;
char*& const p;
const char*& const p;
const char* const& const p;

These all generate compiler errors, because there is no such thing as a constant reference I guess.

const char*& p;
char const*& p;

p is a reference to a pointer to a constant character. One can change p,
but not *p.

char* const& p;

p is a reference to a constant pointer to a character.

const char* const& p;

p is a reference to a constant pointer to a constant character.

const char&* p;
char const&* p;
char& const* p;
char&* const p;
const char& const* p;
const char&* const p;
const char& const* const p;

Fortunately pointers to references are not allowed. The above declarations
are illegal. The programmer who attempts to use the above declarations
should be fired anyway.

const is part of the API of the class to the programmer, to guarantee that the object won’t “change state” across calls to the function(保證對象不會在調用函數時“改變狀態”). Sometimes, your object might have some very internal data that your user couldn’t possibly care about. For example, let’s say you have a class that can send messages on a socket

#include <iostream>
#include<cstring>
using namespace std;
class  X{
private:
    mutable char * buffer;
    int value;
public:
    X(int v = 0, char *b = 0) :value(v), buffer(b){}

    // 這裏爲const,想要修改屬性,必須將被修改的屬性設置爲mutable
    void setBuffer() const{
        char *tmp = new char[20];
        strcpy(tmp, "hello,world!");
        buffer = tmp;           //buffer的值被修改(改變了它的指向)
        cout << buffer << endl;
    }

    // 這裏setBuffer爲const,雖然內部有修改操作,但是修改的
    // 不是屬性buffer的值(指針值),而是修改buffer指向的對象的值
    void modifyBuffer(int index, char value)const
    {
        buffer[index] = value;
        cout << buffer << endl;
    }
    X operator+(const X &rhs) const {
        int value = this->value + rhs.value;
        return X(value);
    }
    void setvalue(int v){ value = v; cout << value << endl; }
    int getvalue(){
        if (buffer)
            cout << buffer << endl;
        return value;
    }
};

int main()
{
    X x;
    x.setvalue(10);    // 10
    x.setBuffer();     // hello,world!
    x.modifyBuffer(5, '.');    // hello.world!
    x.setBuffer();     // hello,world!

    X y(100);

    X z;
    z = x + y;
    cout << z.getvalue() << endl;    // 110

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章