欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++学习笔记---this指针

程序员文章站 2022-07-12 15:38:47
...

一.引言

先从c语言结构体初始化的例子来说明this指针。定义一个结构体,并对其实例进行初始化。

#include<iostream>
#include<string.h>
using namespace std;
struct Student
{
	char name[10];
	int age;
	char sex[2];
};
void InitStudent(<fstruct Student* st char name[], int age, char sex[])
{
	strcpy(st->name, name);
	st->age = age;
	strcpy(st->sex, sex);
}
main()
{
	struct Student s1, s2;
	InitStudent(&s1, "张三", 12, "男");
	InitStudent(&s2, "李四", 14, "男");
}

在Initstudent()函数中,定义了结构体指针,在调用该函数时,传入对应结构体变量的地址,完成对该变量的初始化。

二.this指针

先看下面的代码:

#include<iostream>
#include<string.h>
using namespace std;
class CGoods
{
public:
	void RegisterGoods(char name[], int amount, float price);
	
	void CountTotal();
	
	void GetName(char name[]);

private:
	char Name[10];
	int Amount;
	float Price;
	float Total_value;

};
void CGoods::RegisterGoods(char name[], int amount, float price)
	{
		strcpy(Name, name);
		Amount = amount;
		Price = price;
	}
void CGoods::CountTotal()
	{
		Total_value = Amount * Price;
		cout<<"Total_value:"<<Total_value<<endl;
	}
void CGoods::GetName(char name[])
	{
		strcpy(name, Name);
		cout<<"Name:"<<Name<<endl;
	}

main()
{
	CGoods c1, c2;
	char name[10];
	c1.RegisterGoods("C++", 5, 23);
	c2.RegisterGoods("Java", 4, 24);
	c1.GetName(name);
	c2.GetName(name);
}

  • 提出问题:
    在执行c1.RegisterGoods(“C++”, 5, 23)时,为什么是对c1进行初始化,而不是对c2进行初始化
    同理,在执行
    c1.GetName(name);//为什么返回c1的name,而不是返回c2的name
    c2.GetName(name);//为什么返回c2的name,而不是返回c1的name
  • 解释:
    原来,在指向上述代码时,c++编译器会对代码做如下修改:
#include<iostream>
#include<string.h>
using namespace std;
class CGoods
{
public:
	//void RegisterGoods(CGoods* const this, char name[], int amount, float price);
	void RegisterGoods(char name[], int amount, float price);
	//void CountTotal(CGoods* const this);
	void CountTotal();
	//void GetName(CGoods* const this, char name[]);
	void GetName(char name[]);

private:
	char Name[10];
	int Amount;
	float Price;
	float Total_value;

};
//void RegisterGoods(CGoods* const this, char name[], int amount, float price);
void CGoods::RegisterGoods(char name[], int amount, float price)
	{
		strcpy(Name, name);
		Amount = amount;
		Price = price;
	}
void CGoods::CountTotal()
	{
		Total_value = Amount * Price;
		cout<<"Total_value:"<<Total_value<<endl;
	}
void CGoods::GetName(char name[])
	{
		strcpy(name, Name);
		cout<<"Name:"<<Name<<endl;
	}

main()
{
	CGoods c1, c2;
	char name[10];
	//RegisterGoods(&c1, "C++", 5, 23);
	c1.RegisterGoods("C++", 5, 23);
   //RegisterGoods(&c2, "C++", 5, 23);
	c2.RegisterGoods("Java", 4, 24);
	//GetName(&c1, name);
	c1.GetName(name);
   //GetName(&c2, name);
	c2.GetName(name);
}

即:

- 在每个函数的参数列表中加上CGoods* const this,作为函数的第一个参数。
- 将每个对象对函数的调用改为: c1.GetName(name)->GetName(&c1, name);
this指针就是指向当前对象的指针,其值为对象的内存地址。对象c1调用函数成员,this指针的值就是c1的地址;同理,c2对象调用函数成员,this指针的值就是c2的地址。

三.const关键字

使用const关键字修饰指针,有以下3种情形:

  • const int* p
  • int* const p
  • const int* const p
    可以按照下面的方法理解:
    如果const出现在的左边,那么const锁定的p,不能再对p更改,但是可以更改p的值。即不可以修改p指向的空间的内容,但是可以修改p的指向。
    例如:
    int a = 2;
    int b;
    const int
    p = &a;
    *p = 3;//错误
    p = &b;//正确

如果const出现在的左边,那么const锁定的p,不能再对p更改,但是可以更改p的值。即可以修改p指向的空间的内容,但是不可以修改p的指向。
例如:
int a = 2;
int b;
const int* p = &a;
*p = 3;//正确
p = &b;//错误


如果const出既现在的左边,又出现在的右边,那么const既锁定的p,又锁定*p。这种情形常用来读取