-------无意中逛到的收获,太棒了,虽然文章米有写出来const的重要性,但是对于很多关于const的比较复杂的使用,文章都给出来了,还有很多不合理的使用也给出来,都配有相关的例子,非常好理解。oh ,my god,我爱死这篇文章了!!!
废话少说,上菜!
PS:一个餐前开胃菜是另一篇http://blog.csdn.net/qinyushuang/archive/2010/12/19/6085947.aspx,从这篇文章里面找到一个规律,从右到左,然后再开始下面的阅读吧。
Here's a start. It documents what the keyword "const" means in various places within a declaration. It does not go into the reasons why const-correctness is important. I wrote this several years ago.
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 is a pointer to a const char". Read as such, it is easy to see that
the line *p = 'c'; will not compile.
eg1:
#include<iostream> using namespace std; int main() { char c1 = 'a',c2 = 'b'; const char * p = &c1; cout<< *p<<endl; // *p = 'b'; //error ,assignment of read-only location p = &c2 ;//OK cout<< *p<<endl; c1 = 'c',c2 = 'd'; //OK,c1,c2并不是不能改变,只是不能通过p指针改变 cout<<c1<<c2<<endl; }
The following declaration:
char* const p;
declares p to be a constant pointer to a character. That is:
p = "foo"; // Does not compile
*p = 'f'; // Compiles!
eg2:
#include<iostream> using namespace std; int main() { char c1 = 'a',c2 = 'b'; char * const p = &c1; cout<< *p<<endl; *p = 'c'; //OK cout<<*p<<endl; p = &c2 ;//error ,assighment of read-only variable cout<<c2<<endl; }
And thus:
const char* const p;
char const* const 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';
eg3:
#include<iostream> using namespace std; int main() { const char c1 = 'a'; const char c2 = 'b'; const char * const p = &c1; cout<< *p<<endl; *p = 'c'; //error ,assignment of read-only location cout<<*p<<endl; p = &c2 ;//error ,assighment of read-only variable cout<<c2<<endl; }
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
eg4:
#include<iostream> using namespace std; int main() { const char c1 = 'a'; // char* q = &c1; //error ,invalide conversion from "const char *" to "char *" char const *q = &c1; // char** p = &q; ////error ,invalide conversion from "const char**" to "char**" char const **p = &q; cout<<*q<<endl; cout<<**p<<endl; // *q = 'b'; //error ,assignment of read-only location // c1 = 'b'; //error ,assignment of read-only location // **p = 'b';//error ,assignment of read-only location char c2 = 'b'; q = &c2; cout<<*q<<endl; c2 = 'c'; //warning,but still works // *q = 'd'; //error,assignment of read-only location const char c3 = 'c'; q = &c3; //ok,but still works cout<<*q<<endl; cout<<**p<<endl; const char c4 = 'd'; const char * q2 = &c4; p = &q2; //OK cout<<*q2<<endl; cout<<**p<<endl; }
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
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
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;
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;
And this beast:
const char* const* const p;
p is a constant pointer to a constant pointer to a constant character.
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;
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.