C++ 学习 ::【基础篇:11】:C++ 类的基本使用与非静态 this 指针(两个面试考点):类的空指针问题(this指针可以为空吗?) | this指针存在哪里?

本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下:

  1. 基础篇类与对象(涉及C++的三大特性等);
  2. STL 篇学习使用 C++ 提供的 STL 相关库
  3. 高阶数据结构与算法篇手动实现自己的 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指针可以为空吗?【空指针问题】

5. 相关文章推荐


C++学习合集链接


1. 类的基本使用

注意如下:

  1. 回忆 using 关键字的用法及命名空间的使用建议;
  2. 回忆:类中的成员变量/属性的声明建议;
  3. 回忆:类实例化 => 对象;

注:对象调用成员函数/方法:

  • 对象名.成员函数/方法();
#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 指针相关注意点
  1. 注意 const 是在 * 之后 ,修饰 this 指针,因此:this 指针本身是不可修改的!
  2. this 指针不可修改,但是可以打印,即对象的地址;同时也说明:this 指针就是用于标识当前对象的!this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
  3. 形参和实参位置不能显示传递和接收 this 指针,但是成员函数内部可以使用 this 指针!
  4. 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 】,由于指针为空,使用必出问题!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NPC的白话文谈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值