<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

相关文章
|
11天前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
40 0
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
105 5
|
1月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
97 4
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
114 4
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
126 13
|
6月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
2月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
38 0
|
3月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
143 4
|
4月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
|
4月前
|
C语言
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)