在开发过程中,我们常常需要自定义数据类型,比如自定义结构体等,为了代码的可读性,我们对自定义的类型常常会利用typedef关键字进行重新类型定义。比如:
但在使用typedef的过程中,我们也很容易陷入一些误区,最典型的其中一个是把typedef当作宏展开来理解。如下代码:
对上面的代码,大家很容易展开成如下形式:
const char * cstr;
因此,cstr是一个指向const char的指针,也就是说cstr指向的内容不能修改,但cstr变量本身是可以修改的。事实真的是这样么?最好的办法就是写一个测试程序来验证,如果真的如上面的理解,应该是cstr变量无需初始化,并且可以后面进行再次赋值,只有这样才能说明cstr变量本身是可以被修改的。因此写出如下的测试代码:
编译输出如下错误:
g++ ConstPtr.cpp -o ConstPtr
ConstPtr.cpp: In function 'int main()':
ConstPtr.cpp:8: error: uninitialized const 'cstr'
ConstPtr.cpp:12: error: assignment of read-only variable 'cstr'
make: *** [ConstPtr] Error 1
从编译错误提示可以看到,cstr没有初始化且不能对cstr二次赋值,而这些特性说明,const修饰的是cstr,即cstr是一个const 指针,
因此,上面的等价理解应该是:
char * const cstr;
由于是const的cstr,因此必须进行初始化并且不能二次赋值(正是不能进行二次赋值修改cstr的值,所以c++编译器才强制要求对const变量进行初始化)
也许大家对上面的等价方式感觉有点奇怪,如果我们不用char *定义,而换成如下:
这样大家很容易理解到,const cint ci 等价于:const int ci;
可以看出,此时const修饰的是ci,同理,const cstring cstr,修饰的同样是cstr,只不过,cstr是一个char *类型而已。