<C++>一篇文章搞懂类和对象中常函数和常对象的实质以及避免空指针访问的小妙招

简介: <C++>一篇文章搞懂类和对象中常函数和常对象的实质以及避免空指针访问的小妙招

常函数


概念:成员函数后加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=agethis指针的实质是一个指针常量,特点不能修改指向的地址但是可以修改值,下面解释一下指针常量和常量指针的区别。


指针常量和常量指针的区别


指针常量不可以修改指针的指向,可以修改指向该地址的值,例如 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称该对象为常对象


image.png


按照概念所述创建常对象S,然后我对年龄和学号进行赋值,结果是年龄无法改变,原因是学号前加了mutable关键字,此时的学号就变成了一个特殊的属性,即使在常函数和常对象中也可以修改属性。


常对象调用问题


常对象只能调用常函数


举例:


image.png


这里的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,必定会引发异常,如图所示:


image.png


想必大家很熟悉吧,这就是空指针异常;由于s指向NULL,没有地址,this代表着成员s的地址,所以怎么可能在空地址访问出值呢,显然这是不可能的,会引发上面的异常。但是我们可以加上判断语句来防止空指针访问,在输出语句前加上if(this==NULL){return ;} 这样就可以在this是空指针的情况下停止程序运行,增加程序的健壮性。


不用this指针


对于不需要访问地址的成员函数,空指针可以直接访问,我把showStudent函数加注释,只调用showAge函数就不会报错,运行结果如图所示:


image.png

相关文章
|
1天前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类
|
1天前
|
安全 程序员 编译器
【C++类和对象】初始化列表与隐式类型转换
【C++类和对象】初始化列表与隐式类型转换
|
8天前
|
存储 编译器 C++
c++的学习之路:6、类和对象(2)
c++的学习之路:6、类和对象(2)
22 0
|
8天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
23 0
|
8天前
|
C++
c++的学习之路:7、类和对象(3)
c++的学习之路:7、类和对象(3)
20 0
|
1天前
|
安全 编译器 C++
【C++类和对象】const成员函数及流插入提取
【C++类和对象】const成员函数及流插入提取
|
1天前
|
存储 C++
【C++类和对象】日期类的实现(下)
【C++类和对象】日期类的实现
|
1天前
|
编译器 C++
【C++类和对象】日期类的实现(上)
【C++类和对象】日期类的实现
|
1天前
|
编译器 C++ 索引
【C++类和对象】拷贝构造与赋值运算符重载(下)
【C++类和对象】拷贝构造与赋值运算符重载
|
1天前
|
存储 编译器 C++
【C++类和对象】拷贝构造与赋值运算符重载(上)
【C++类和对象】拷贝构造与赋值运算符重载