Note:
i.视频为黑马程序员C++视频,系列文章为视频听课笔记;
ii.难度指数:+
iii.不论变量、函数名、标识符形式怎样复杂,只要我们考虑编程的本质是对内存的操作,对内存进行分析,一切逻辑都会变得清晰。
一、空指针
示例一:定义整型指针p
为空指针。
int *p = NULL
示例二:定义类指针p
为空指针。
#include<iostream>
#include<string>
using namespace std;
class person
{
public:
//打印类的名称
void showClassName()
{
cout << "this is a person class" << endl;
}
//打印类中的年龄属性
void showAge()
{
cout << "年龄为:" << m_Age << endl;//等价于cout << "年龄为:" << this->m_Age << endl;
}
int m_Age;
};
void test01()
{
person *p = NULL;//指针还能定义为person类,就是类指针。也可以看做创建了一个实例,但其分配的地址为空。
p->showClassName();
p->showAge();//报错,p无分配内存,不包含成员属性
}
int main()
{
test01();
}
示例二代码无法正常执行,显示异常如下:原因是定义类指针*p
为空指针,即创建的实例对象p
无对应内存,因此无法输出成员属性。
二、const修饰成员函数(常函数)
在学习第二部分内容之前,需要了解以下两点:
(1)类中的每个成员函数中都会包含一个this指针,指向当前调用该成员函数的实例对象。
(2)this指针本质上是一个指针变量,假定类person
中某成员函数为func()
,当person
类的某一实例对象调用成员函数func()
时,this指针指向该实例对象,由于this指针的本质是一个指针变量,即其指向不变,但指向的值可以改变。因此,在成员函数func中,改变this指针指向的操作是不允许的。但当该实例对象结束对func()
的调用时,this指针还是可以指向其他调用func()
的实例对象。总之,“this指针本质上是一个指针变量”这一概念准确来说只在实例对象调用该成员函数期间成立。
1.code格式
在成员函数后面加const,代码示例如下所示,函数ShowPerson()也称为常函数。
class person
{
public:
//const修饰成员函数ShowPerson
void ShowPerson() const
{
m_A = 100;//报错,显示m_A无法修改
}
int m_A;
};
2.作用
在成员函数后面加const,修饰的是该成员函数中包含的this指针,作用是让this指针指向的值也不可以改变。
【一点思考】:this指针指向的实际上是一个类的实例对象,应该没有具体的值,这里“指向的值”指的其实是实例对象的成员属性,即类的成员属性。
那么,有没有一种方法可以让类的成员属性在常函数中也可以修改呢?
引入关键词
mutable
。
代码示例:
class person
{
public:
void showperson2() const
{
m_A = 100;//报错,显示m_A无法修改
m_B = 200;//不报错,说明m_B可以在常函数中被修改
}
int m_A;
mutable int m_B;
};
三、常对象
1.code格式
在创建的实例对象前面加const,代码示例如下所示,其中,实例对象p
即为常对象。
class person
{
public:
int m_A;
mutable int m_B;
};
void test01()
{
const person p;//常对象定义格式
}
2.作用
常对象不能修改(普通的)成员属性,可以修改(mutable)修饰的成员属性。
代码示例:
class person
{
public:
int m_A;
mutable int m_B;
};
void test01()
{
const person p;//常对象定义格式
p.m_A = 100;//报错,常对象不能修改(普通的)成员属性
p.m_B = 200;//不报错
}
当常对象修改(普通的)成员函数属性时,error如下图所示:
3.注意事项
- 常对象只能调用常函数,不能调用普通成员函数;
【一点理解】:假设常对象可以调用普通成员函数,已知普通成员函数中可以对(普通的)成员属性进行修改,与常对象的定义矛盾,因此常对象不可以调用普通的成员函数。