常函数
概念:成员函数后加const后我们称这个函数为常函数
详解常函数概念
class Student { public: void setAge(int age) const { m_age = age; } int m_age; int m_no; }; void test1() { Student S1; S1.m_age = 100; }
这里我简单的设计了一个学生类,添加属性年龄和学号;添加设置学生年龄的成员函数setAge,并在主函数中修改年龄属性;实际上这个写法是错的,因为加上const后成员函数内的属性无法修改,这是为什么呢,其实上面的代码隐藏了this指针的写法,完整的代码应该是this->m_age=age,而this指针的实质是一个指针常量,特点不能修改指向的地址但是可以修改值,下面解释一下指针常量和常量指针的区别。
指针常量和常量指针的区别
指针常量不可以修改指针的指向,可以修改指向该地址的值,例如 int * const p;
常量指针可以修改指针的的指向,不可以修改地址对应的值, 例如 int const *p;
解释:
void showAge() { this->m_age=20; }
这里我把编译器默认的形式写了出来,而这个this指针应该是Student * const this;的形式,可以修改this的值但是不能修改this的指向,我们把const加上就可以把这个成员函数变为常函数,但是加在哪儿呢,放括号里肯定不合适,因为那是传参的地方,放函数名前面也不合适,那是返回值类型,所以我们把const放在最后面,这时this指针就变成了constStudent * const this的形式,既不能改变指针指向也不能改变值,这样常函数内的属性就变为了const修饰的常量,无法修改;但是真的无法修改吗,答案是否定的,我们可以声明属性的时候加上mutable关键字,例如:
void setNo(int no) const { this->m_no = 1001; } mutable int m_no;
这里的setNo是一个常函数,但是我通过在int m_no前面加上mutable 关键字完成了修改,这是C++的一个特点。
常对象
概念
声明对象前加const称该对象为常对象
按照概念所述创建常对象S,然后我对年龄和学号进行赋值,结果是年龄无法改变,原因是学号前加了mutable关键字,此时的学号就变成了一个特殊的属性,即使在常函数和常对象中也可以修改属性。
常对象调用问题
常对象只能调用常函数
举例:
这里的func不是常函数,这里的报错提示是 存在“不兼容的类型限定符“;意思就是类对象S的属性无法修改,但是如果调用不是常函数的func就可能导致成员属性发生改变,这就是所谓的类型限定符不兼容。
空指针访问
C++中空指针也是可以调用成员函数的,但是一定要判断有没有用到this指针
示例:
class Student { public: void showAge() { cout << "我的年龄为20岁" << endl; } void showStudent() { cout <<"age="<< m_age << endl; } int m_age; }; void test1() { Student* s = NULL; s->showAge(); s->showStudent(); }
使用this指针
如果我在主函数调用test1,必定会引发异常,如图所示:
想必大家很熟悉吧,这就是空指针异常;由于s指向NULL,没有地址,this代表着成员s的地址,所以怎么可能在空地址访问出值呢,显然这是不可能的,会引发上面的异常。但是我们可以加上判断语句来防止空指针访问,在输出语句前加上if(this==NULL){return ;} 这样就可以在this是空指针的情况下停止程序运行,增加程序的健壮性。
不用this指针
对于不需要访问地址的成员函数,空指针可以直接访问,我把showStudent函数加注释,只调用showAge函数就不会报错,运行结果如图所示: