There are two kinds of interactions between pointers and the const qualifier: We can have pointers to const objects and pointers that are themselves const.
More details about this topic can be found in 4.2.5 section in C++ Primer,Fourth Edition(Chinese p.110).
The following example is used to illustrate this topic.
#include <iostream> #include <string> using namespace std; int main() { const string str1 = "hello,csdn!"; const string str2 = "hello,wcdj!"; /************************************************ * 指向string类型const对象的non-const指针 *************************************************/ //sp1是一个指向string类型const对象的non-const指针,sp1指向可以修改,但*sp1的内容不能修改 const string *sp1; sp1 = &str1; cout << "*sp1: " << *sp1 << endl;//输出:hello,csdn! //修改sp1的指向 sp1 = &str2; cout << "*sp1: " << *sp1 << endl;//输出:hello,wcdj! //修改*sp1的内容 //*sp1="modified";//通不过编译 //cout << "*sp1: " << *sp1 << endl; /************************************************ * 指向string类型non-const对象的const指针(必须初始化) *************************************************/ //sp2是一个指向string类型non-const对象的const指针, //str1是一个string类型const对象, //要求指向它的指针必须为一个指向string类型const对象的(const或non-const)指针 //string *const sp2= &str1;//通不过编译 //sp2是一个指向string类型non-const对象的const指针,*sp2的内容可以修改,但sp2指向不能修改 string str3="123"; string *const sp2=&str3;//必须初始化 //修改*sp2的内容 string str4="456"; *sp2=str4; cout << "*sp2: " << *sp2 << endl;//输出:456 cout << "str3: " << str3 << endl;//输出:456 (str3的内容改变了) //修改sp2的指向 str4="789"; //sp2=&str4;//通不过编译 /************************************************ * 指向string类型const对象的const指针(必须初始化) ************************************************/ //sp3是一个指向string类型const对象的const指针,*sp3的内容不能修改,而且sp3指向也不能修改 const string *const sp3=&str1; cout << "*sp3: " << *sp3 << endl;//输出:hello,csdn! //修改sp3的指向 //sp3=&str2;//通不过编译 error C2166: l-value specifies const object //修改*sp3的内容 //*sp3=str2;//通不过编译 /************************************************ * 注意: * const修饰符可以放在所修饰类型的前面或者后面, * 所以,string const *和const string *等价 * 很多人喜欢放在前面,但是我认为放在类型的后面更容易理解(即const修饰前面的类型)。 ************************************************/ string const *sp5;//string const *sp5即为const string *sp5 sp5= &str1; cout << "*sp5: " << *sp5 << endl;//输出:hello,csdn! system("pause"); return 0; }
Notice:
Pointers and Typedefs
The use of pointers in typedefs (Section 2.6) often leads to surprising results. Here is a question almost everyone answers incorrectly at least once. Given the following,
typedef string *pstring; const pstring cstr;
what is the type of cstr? The simple answer is that it is a pointer to const pstring. The deeper question is: what underlying type does a pointer to const pstring represent? Many think that the actual type is
const string *cstr; // wrong interpretation of const pstring cstr
That is, that a const pstring would be a pointer to a constant string. But that is incorrect.
The mistake is in thinking of a typedef as a textual expansion. When we declare a const pstring, the const modifies the type of pstring, which is a pointer. Therefore, this definition declares cstr to be a const pointer to string. The definition is equivalent to
// cstr is a const pointer to string string *const cstr; // equivalent to const pstring cstr
Advice: Understanding Complicated const Type Declarations
Part of the problem in reading const declarations arises because the const can go either before or after the type:
string const s1; // s1 and s2 have same type, const string s2; // they're both strings that are const
When writing const definitions using typedefs, the fact that the const can precede the type can lead to confusion as to the actual type being defined:
string s; typedef string *pstring; const pstring cstr1 = &s; // written this way the type is obscured pstring const cstr2 = &s; // all three decreations are the same type string *const cstr3 = &s; // they're all const pointers to string
Putting the const after pstring and reading the declaration from right to left makes it clearer that cstr2 is a const pstring, which in turn is a const pointer to string.
Unfortunately, most readers of C++ programs expect to see the const before the type. As a result, it is probably a good idea to put the const first, respecting common practice. But it can be helpful in understanding declarations to rewrite them to put the const after the type.