在成员函数的声明后添加const关键字即成为常量成员函数:
// <return_type> <function_name>() const;
int get_data() const;
常量成员函数本质上意味着该函数不会修改其所在对象的内容。
普通指针无法绑定一个常量对象
const double pi = 3.14;
double *ptr = π // C2440 “初始化”: 无法从“const double *”转换为“double *”
这段代码会抛出一个错误,原因很简单,pi为常量,不允许改变pi的值,因此不可以用一个普通指针指向常量pi,正确的做法是在声明指针时使用const关键字:
const double pi = 3.14
const double *ptr = π
这样ptr就成为了一个“指向常量的指针”(pointer to const)。
注,C++ Primer(中文版)一书中,将const pointer翻译为“常量指针”,pointer to const翻译为“指向常量的指针”。前面提到的普通指针则指常量指针和非常量指针:
const double *ptr; // 指向常量的指针
double const *ptr; // 指向常量的指针, 两种写法等价
// 普通指针
double * ptr; // 非常量指针
double * const ptr; // 常量指针
this 常量指针
学习C++ ×
学习绕口令 √
默认情况下,
this的类型是指向类类型非常量版本的常量指针。By default, the type of
thisis a const pointer to the nonconst version of the class type.例如,在
Sales_data成员函数中,this的类型是Sales_data *const。For example, by default, the type of
thisin aSales_datamember function isSales_data *const.尽管
this是隐式的,但它仍然需要遵循初始化规则,意味着(在默认情况下)我们不能把this绑定到一个常量对象上。Although
thisis implicit, it follows the normal initialization rules, which means that (by default) we cannot bind this to a const object.
class Dog
{
public:
std::string name = "null";
void print_name()
{
std::cout << this->name << std::endl;
}
void print_name_const() const // 常量成员函数
{
std::cout << this->name << std::endl;
}
}
int main()
{
const Dog dog;
dog.print_name(); // 报错,C2662 “void Dog::print_name(void)”: 不能将“this”指针从“const Dog”转换为“Dog &”
dog.print_name_const(); // 正确运行
return 0;
}
main函数第一行中创建了一个常量对象dog,意味着dog对象的内容不允许被修改;前面提到了,默认情况下,传给成员函数的
this是一个常量指针,即Dog *const,也就无法将其直接绑定到常量对象上;我们已经把
dog声明为了常量对象,所以我们需要把this修改为指向常量的指针,即const Dog *const,才能正常调用dog的成员函数;但是
this是隐式传递给成员函数的,例如print_name()函数的参数列表中并没有显式包含this,也就意味着无法直接通过函数参数修改this类型;那么如何把
this修改为const Dog *const类型呢?C++提供了这样一个方法:在声明成员函数时,末尾添加const,使之成为常量成员函数,如本例的print_name_const()。
总结
传给成员函数的this指针,其类型为常量指针,意味着可以通过this修改其指向的对象的内容,但不能修改this指向的对象。
传给常量成员函数的this指针,其类型为指向常量的常量指针,意味着既不可以通过this修改其指向的对象的内容,也不能修改this指向的对象。
对于一个类的const实例,只能调用其const成员函数。