本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下:
- 基础篇:类与对象(涉及C++的三大特性等);
- STL 篇:学习使用 C++ 提供的 STL 相关库;
- 高阶数据结构与算法篇: 手动实现自己的 STL 库 及 设计实现高阶数据结构,如 B树、B+树、红黑树等。
学习集:
本期内容:C++ 类的基本使用与非静态 this 指针介绍说明
目录:
1. 类的基本使用:部分知识回顾
2. 提出问题:如何区分不同实例对象【this 指针】
3. this 指针相关注意点运行结果测试
- - 3.1 关于 this 指针的注意点
- - 3.3 this 指针测试:this 指针可用于区分对象
- - 3.3 形参和实参位置不能显示传递和接收 this 指针
4. 面试提问:
- - 4.1 this指针存在哪里?
- - 4.2 this指针可以为空吗?【空指针问题】
【 C++学习合集链接 】
1. 类的基本使用
注意如下:
- 回忆 using 关键字的用法及命名空间的使用建议;
- 回忆:类中的成员变量/属性的声明建议;
- 回忆:类实例化 => 对象;
注:对象调用成员函数/方法:
- 对象名.成员函数/方法();
#include<iostream>
using std::cout; // 为什么不用 using namespace std ?
using std::endl;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1, d2; // 实例化对象
/* 对象名.成员函数/方法(); */
d1.Init(2023, 5, 21); // 输出:2023-5-21
d2.Init(2023, 5, 22); // 输出:2023-5-22
d1.Print();
d2.Print();
return 0;
}
2. 提出问题:如何区分不同实例对象【this 指针】
以上代码是我们正常写出的类代码。请问类在实例化后(如上两个实例化对象),在打印的时候是如何区分并正确打印出如我们预想的结果?
答:this 指针!【 以下是编译器处理后的代码:供参考 】
【 该示例仅是在程序编译是编译器的处理方式! 】
- 注意参数列表变化!
- 注意对象调用函数时的传参变化!
说明:在实际编码中,this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。我们只需知道,this 指针可以用户辨识我们当前操作的对象!
class Date
{
public: // 注意此处:参数列表变化
void Init(Date* const this, int year, int month, int day)
{
/* 成员变量前均添加 this 指针 */
this->_year = year;
this->_month = month;
this->_day = day;
}
// 注意此处:参数列表变化
void Print(Date* const this)
{
cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1, d2;
// 注意对象调用函数时的传参变化!
d1.Init(&d1, 2023, 5, 21); // 注意第一个参数
d2.Init(&d2, 2023, 5, 22); // 注意第一个参数
d1.Print(&d1);
d2.Print(&d2);
return 0;
}
3. this 指针相关注意点运行结果测试
3.1 this 指针相关注意点
- 注意 const 是在 * 之后 ,修饰 this 指针,因此:this 指针本身是不可修改的!
- this 指针不可修改,但是可以打印,即对象的地址;同时也说明:this 指针就是用于标识当前对象的!this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- 形参和实参位置不能显示传递和接收 this 指针,但是成员函数内部可以使用 this 指针!
- this 指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
3.2 this 指针测试:this 指针可用于区分对象
注:this 指针不可修改,但是可以打印,即对象的地址;同时也说明:this 指针就是用于标识当前对象的!
/* 执行此代码结果! */
int main() {
Date d1, d2;
d1.Init(2022, 1, 11);
d2.Init(2022, 1, 12);
cout << &d1 << endl;
d1.Print();
cout << &d2 << endl;
d2.Print();
return 0;
}
3.3 this 指针测试:形参和实参位置不能显示传递和接收 this 指针
形参和实参位置不能显示传递和接收 this 指针,但是成员函数内部可以使用 this 指针!
4. 面试提问
4.1 this指针存在哪里?
- this指针存在哪里?
- 存储在:栈区!(形参)【但是可能存在使用寄存器优化!若频繁访问,存储在寄存器提高访问速率!(该情形取决于编译器处理方式:如:vs 编译器)】
4.2 this指针可以为空吗?【空指针问题】
- this指针可以为空吗? 可以!
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
return 0;
}
第一个:正常运行!虽然指针为 nullptr ,但是 Print() 函数并没有使用 this 指针!
第二个:运行崩溃!与上一个不同的是 _a 【实际就是 this._a 】,由于指针为空,使用必出问题!