• C++:C++基础:C++关键字:this指针


    this用法

    • this 实际上是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给 this。不过 this 这个形参是隐式的,它并不出现在代码中,而是在编译阶段由编译器默默地将它添加到参数列表中。
    • this 作为隐式形参,本质上是成员函数的局部变量,所以只能用在成员函数的内部,并且只有在通过对象调用成员函数时才给 this 赋值。在函数体中所有“成员变量” 的操作,都是通过该指针去访问。
    • 成员函数最终被编译成与对象无关的普通函数,除了成员变量,会丢失所有信息,所以编译时要在成员函数中添加一个额外的参数,把当前对象的首地址传入,以此来关联成员函数和成员变量。这个额外的参数,实际上就是 this,它是成员函数和成员变量关联的桥梁。

    this指针理解 :

    • class应该理解为一种类型,象int,char一样,是用户自定义的类型。用这个类型可以来声明一个变量,比如int x, myclass my等等。这样就像变量x具有int类型一样,变量my具有myclass类型。理解了这个,就好解释this了,my里的this 就是指向my的指针。如果还有一个变量myclass mz,mz的this就是指向mz的指针。这样就很容易理解this 的类型应该是myclass ,而对其(mz)的解引用this就应该是一个myclass类型的变量。
    • 一个学生可以有多本书一样,而这些书都是属于这个同学的;同理,如果有很多个同学在一起,那么为了确定他们的书不要拿混淆了,最好的办法我想应该就是每个同学都在自己的书上写上名字,这样肯定就不会拿错了。同理,一个对象的多个成员就可看作是这个对象所拥有的书;而在很多个对象中间,我们为了证明某个成员是自己的成员,而不是其他对象的成员,我们同样需要给这些成员取上名字。在C++中,我们利用this指针帮助对象做到这一点,this指针记录每个对象的内存地址,然后通过运算符->访问该对象的成员。
    • 关于this指针一个比较经典的回答:当你进入一个房子后,你可以看见桌子,椅子,地板等,但是这个房子的全貌你是看不到的,那么对于一个类的实例来说,你也可以看到它的成员函数,成员变量。但是这个实例本身了?this就是一个指针,它时时刻刻指向这你这个实例本身。

    this 五大特性:

    1.  this指针的类型是 类类型* const (指针常量)

    2.  this指针并不是对象本身的一部分,不会影响sizeof的结果

    3.  this的作用域在类成员函数的内部

    4.  this指针是类成员函数的第一个默认隐含参数,编译器自动维护传递

    5.  只有在类的非静态成员函数中才可以使用this指针

    1:this的作用域在类成员函数的内部

    我们先看下面这个例子

    1. #include
    2. #include
    3. using namespace std;
    4. class Student {
    5. private:
    6. char* m_name;
    7. int m_age;
    8. float m_score;
    9. public:
    10. void setage(int m_age);
    11. //声明构造函数
    12. Student(char* name, int age, float score);
    13. //声明普通成员函数
    14. void show();
    15. };
    16. //定义构造函数
    17. Student::Student(char* name, int age, float score) {
    18. m_name = name;
    19. m_age = age;
    20. m_score = score;
    21. }
    22. // c++变量的作用域问题,函数形参跟你的变量重名,在函数内部,c++会仍然使用函数形参,也就是现在真正的类变量m_age是没有调用到的!
    23. void Student::setage(int m_age) {
    24. m_age = m_age;
    25. }
    26. //定义普通成员函数
    27. void Student::show() {
    28. cout << m_name << "的年龄是" << m_age << ",成绩是" << m_score << endl;
    29. }
    30. int main() {
    31. //创建对象时向构造函数传参
    32. string name = "李雷";
    33. Student stu((char*)name.c_str(), 5, 92.5f);
    34. stu.setage(10);
    35. stu.show();
    36. //创建对象时向构造函数传参
    37. string name1 = "韩梅梅";
    38. Student* pstu = new Student((char*)name1.c_str(), 15, 96);
    39. pstu->setage(20);
    40. pstu->show();
    41. return 0;
    42. }
    43. // 打印
    44. 李雷的年龄是5,成绩是92.5
    45. 韩梅梅的年龄是15,成绩是96
    • 输出结果是李雷的年龄是5,成绩是92.5;韩梅梅的年龄是15,成绩是96。可能有些读者感到疑惑,年龄为什么不是10,20呢?
    • 真正的原因是c++变量的作用域问题,函数形参跟你的变量重名,在函数内部,c++会仍然使用函数形参,也就是现在真正的类变量m_age是没有调用到的!

    那么如何解决这个问题?

    1. 避免避免形参数和类变量重名 
    2. 使用this指针
    1. #include
    2. using namespace std;
    3. class Student {
    4. private:
    5. char* m_name;
    6. int m_age;
    7. float m_score;
    8. public:
    9. void setage(int m_age);
    10. //声明构造函数
    11. Student(char* name, int age, float score);
    12. //声明普通成员函数
    13. void show();
    14. };
    15. //定义构造函数
    16. Student::Student(char* name, int age, float score) {
    17. m_name = name;
    18. m_age = age;
    19. m_score = score;
    20. }
    21. void Student::setage(int m_age) {
    22. this->m_age = m_age;
    23. }
    24. //定义普通成员函数
    25. void Student::show() {
    26. cout << m_name << "的年龄是" << m_age << ",成绩是" << m_score << endl;
    27. //cout<m_name<<"的年龄是"<m_age<<",成绩是"<m_score<
    28. }
    29. int main() {
    30. //创建对象时向构造函数传参
    31. string name = "李雷";
    32. Student stu((char*)name.c_str(), 5, 92.5f);
    33. stu.setage(10);
    34. stu.show();
    35. //创建对象时向构造函数传参
    36. string name1 = "韩梅梅";
    37. Student* pstu = new Student((char*)name1.c_str(), 15, 96);
    38. pstu->setage(20);
    39. pstu->show();
    40. return 0;
    41. }
    42. // 打印结果
    43. 李雷的年龄是10,成绩是92.5
    44. 韩梅梅的年龄是20,成绩是96

    2:证明一下 this 的值就是当前对象的值

    1. #include
    2. using namespace std;
    3. class Student {
    4. private:
    5. char* m_name;
    6. int m_age;
    7. float m_score;
    8. public:
    9. void setage(int m_age);
    10. //声明构造函数
    11. Student(char* name, int age, float score);
    12. //声明普通成员函数
    13. void show();
    14. // 打印this的值
    15. void printThis();
    16. };
    17. //定义构造函数
    18. Student::Student(char* name, int age, float score) {
    19. m_name = name;
    20. m_age = age;
    21. m_score = score;
    22. }
    23. void Student::setage(int m_age) {
    24. this->m_age = m_age;
    25. }
    26. //定义普通成员函数
    27. void Student::show() {
    28. cout << m_name << "的年龄是" << m_age << ",成绩是" << m_score << endl;
    29. //cout<m_name<<"的年龄是"<m_age<<",成绩是"<m_score<
    30. }
    31. void Student::printThis() {
    32. cout << this << endl;
    33. }
    34. int main() {
    35. //创建对象时向构造函数传参
    36. string name1 = "韩梅梅";
    37. Student* pstu = new Student((char*)name1.c_str(), 15, 96);
    38. pstu->printThis();
    39. cout << pstu << endl;
    40. // const char *“ 类型的值不能用于初始化 “char *“ 类型的实体
    41. char *p = (char*)"张三"; //使用强制类型转换
    42. Student* pstu1 = new Student(p, 15, 96);
    43. pstu1->printThis();
    44. cout << pstu1 << endl;
    45. return 0;
    46. }
    47. // 打印输出
    48. 00FDFC90
    49. 00FDFC90
    50. 00FDFC58
    51. 00FDFC58

  • 相关阅读:
    目标检测笔记(十三): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程))
    使用GoFrame+Vue+ElementUI框架搭建的管理系统
    uniapp canvas 无法获取 webgl context 的问题解决
    如何通俗理解超级浏览器?可以用于哪些场景?有哪些品牌?
    jQuery
    使用vite+react搭建项目踩坑记录
    租用香港服务器您需要知道的5件事
    深度学习 paper 代码复现参考
    【面试系列】Java面试知识篇(一)
    算法 学习杂谈
  • 原文地址:https://blog.csdn.net/u013620306/article/details/127896058