当const指针遇到const引用
1. 概念阐述
首先,咱们先理清这么几个概念:const指针;指向const对象的指针;const引用;指向const对象的引用。
const指针定义:Type *const ptr = NULL;
这里const指针跟其它普通的const变量如const int i;没有啥本质的区别。只不过变量变成了指针变量罢了,所以ptr在定义时必须要初始化,否则编译错误。
指向const对象的指针的定义:const Type* ptr;
ptr是指向const对象的指针,即不能通过*ptr来改变对象的值。此时,ptr本身并不是个常量类型,所以在定义的时候不是必须要初始化。此外,关于ptr的赋值,既可以将非const对象的地址赋给ptr,也可以将const对象的指针赋给ptr。但是不管ptr所指的对象能不能发生改变,都不能通过ptr来间接地对所指对象做写操作。
指向const对象的引用的定义: const int& ref = i; 或者 int const& ref = i;
跟指向const对象的指针类似,不管变量i是不是const类型,都不能对ref做写操作。
const引用定义:const int& ref = i;
看到这里,不要感觉奇怪。const引用和指向const对象的引用本来就是同一种说法。回忆一下,引用类型在定义的时候都必须提供初始化,此后就不能再更改引用其他对象。如果你愿意,可以这么认为:所有的引用类型都是常引用。因为引用一旦指定,就不能更改,所能做的就只是通过引用对其所
引用的对象的值进行更改。在C++术语里面,大家一般都把指向const对象的引用称为是const引用。所以你一般看到的const引用的定义其实就是指向const对象的引用的定义了。
2.一个问题
下面就刚才所阐述的几个概念,试想一下这么一个问题:对函数void Test(const char*& ptr);进行Test("1111");调用会出现编译错误不?
分析:对Test形参类型从右往左读,首先,ptr是一个引用类型;然后,ptr引用的是一个指向常字符的指针。所以不能通过ptr来对所指对象做更改,但是可以对ptr的值做更改。毕竟,ptr不是一个常类型,指向的对象是个常类型。进行Test("1111”)调用时,由于“1111”会转化为const char* const类型,即指向常字符的常指针类型,所以既不能对实参指针本身做写操作,也不能对实参所指对象做写操作。得出的结论就是:Test("1111")调用会出现编译错误。
修改方法就是:void Test(const char* const& ptr);
附:
#include <iostream>
using namespace std;
void Test(const char *& ptr) // this should be modified as: void Test(const char* const& ptr)
{
cout << "ptr = " << ptr << endl;
}
int main()
{
Test("1111");
return 0;
}
上述代码出出现编译错误,错误信息如下:
const.cpp: 在函数‘int main()’中:
const.cpp:20:13: 错误: 用类型为‘const char*’的右值初始化类型为‘const char*&’的非常量引用无效
const.cpp:5:6: 错误: 在传递‘void Test(const char*&)’的第 1 个实参时
const.cpp:20:13: 错误: 用类型为‘const char*’的右值初始化类型为‘const char*&’的非常量引用无效
const.cpp:5:6: 错误: 在传递‘void Test(const char*&)’的第 1 个实参时