原问是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;
}