第10章 对象和类——对象和类(三) this指针

文章介绍了如何在C++中使用this指针解决类方法中涉及两个对象的问题,通过`getMaxObj`函数比较并返回总分较大的学生对象,同时强调了const修饰符在函数声明中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文章是作者根据史蒂芬·普拉达所著的《C++ Primer Plus》而整理出的读书笔记,如果您在浏览过程中发现了什么错误,烦请告知。另外,此书由浅入深,非常适合有C语言基础的人学习,感兴趣的朋友可以自行阅读此书籍。

this指针

我们在上一个文章《第10章 对象和类——对象和类(二) 类的构造函数和析构函数》的最后,完善了Student类。

该类声明如下:

// student.hpp
#ifndef _STUDENT_H_
#define _STUDENT_H_
#include <string>
using namespace std;
class Student{
private:
    string m_id;
    string m_name;
    int m_yuwen;
    int m_shuxue;
    int m_yingyu;
    int m_total;
    int m_avr;
    void set_total() { m_total = m_yuwen + m_shuxue + m_yingyu;}
    void set_avr() { m_avr = m_total/3;}
public:
    Student();
    Student(const string &id, const string &name, 
            int yuwen = 0, int shuxue = 0, int yingyu = 0);
    ~Student();
    void display();
};

#endif

我们可以看到,每个类成员函数都只涉及一个对象,即调用它的对象。但有时候方法可能涉及到两个对象,在这种情况下需要使用C++的this指针。

假设针对Student类有一个新的需求,需要比较两个学生的总分,然后返回总分比较大的那个学生。

我们要确认这个成员函数的原型,首先,它要返回一个对象,其次,它需要比较两个对象的总分并返回较大的那个的对象。另外,我们只是为了比较大小,并不是要去修改某个对象,因此我们需要使用const来限制修改。

我们很容易就想到了如下的原型。

const Student& getMaxObj(const Student& st) const;

关于const的说明:

  • 第一个const表示我们返回一个Student对象的引用,这个对象返回之后不可被修改。
  • 第二个const表示我们接收一个Student对象的引用,类方法中不可修改此对象,比如st1.getMaxObj(st2), st2就是此对象,此方法中不可修改st2的成员。
  • 第三个const表示getMaxobj函数为"const成员函数",类方法中不可修改调用对象,比如st1.getMaxObj(st2),st1就是调用对象,此方法中不可修改st1的成员。

但当我们想要实现这个方法时,我们发现出现了问题:

const Student& Student::getMaxObj(const Student& st) const
{
    if(st.m_total > m_total)
    {
      return st;
    }
    else
    {
      return ???;   //此处应该返回什么?
    }
}

C++解决这种问题的方法是:使用被称为this的特殊指针。this指针指向用来调用成员函数的对象(this被作为隐藏参数传递给方法)。这样的话,st1.getMaxObj(st2)将this设置为st1对象的地址,使得这个指针可用于getMaxObj方法。同样,函数调用st2.getMaxObj(st1)将this设置为st2对象的地址。

一般来说,所有的类方法都将this指针设置为调用它的对象的地址。也就是说,getMaxObj()中的m_total,其实也可以写成this->m_total。

每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。

然而,要返回的并不是this,因为this是对象的地址,而不是对象本身,即 * this(将解除引用运算符*用于指针,将得到指针指向的值)。

this为调用对象的地址,*this即为调用对象,基于此,我们可以完成前面的定义。

const Student& Student::getMaxObj(const Student& st) const
{
    if(st.m_total > m_total)
    {
      return st;
    }
    else
    {
      return *this;   //返回当前调用对象。
    }
}

我们继续完善下Student类:

// student.hpp
#ifndef _STUDENT_H_
#define _STUDENT_H_
#include <string>
using namespace std;
class Student{
private:
    string m_id;
    string m_name;
    int m_yuwen;
    int m_shuxue;
    int m_yingyu;
    int m_total;
    int m_avr;
    void set_total() { m_total = m_yuwen + m_shuxue + m_yingyu;}
    void set_avr() { m_avr = m_total/3;}
public:
    Student();
    Student(const string &id, const string &name, 
            int yuwen = 0, int shuxue = 0, int yingyu = 0);
    ~Student();
    void display() const;         //显示信息不需要修改对象成员,我们将其声明为const成员函数
    const Student& getMaxObj(const Student& st) const;
};

#endif
//student.cpp
#include <iostream>
#include <string>
#include "student.hpp"
using  namespace std;
Student::Student()
{
    m_id = "no id";
    m_name = "no name";
    m_yuwen = 0;
    m_shuxue = 0;
    m_yingyu = 0;
    m_total = 0;
    m_avr = 0;
    cout << "create obj: " << this->m_name << endl;
}
Student::~Student()
{
    cout << "delete obj: " << this->m_name << endl;
}
Student::Student(const string &id, const string &name, int yuwen, int shuxue, int yingyu)
{
    m_id = id;
    m_name = name;
    m_yuwen = yuwen;
    m_shuxue = shuxue;
    m_yingyu = yingyu;
    set_total();
    set_avr();
    cout << "create obj: " << this->m_name << endl;
}
void Student::display() const
{
   cout << "show info: " << endl; 
   cout << m_id << " " << m_name << endl 
        << "yuwen: " << m_yuwen << endl 
        << "shuxue: " << m_shuxue << endl 
        << "yingyu: " << m_yingyu<< endl 
        << "total : " << m_total << endl
        << "avr : " << m_avr << endl; 
}
const Student& Student::getMaxObj(const Student& st) const
{
    if(st.m_total > m_total)
    {
      return st;
    }
    else
    {
      return *this;
    }
}

我们可以使用如下的方式来使用:

//student_main.cpp
#include <iostream>
#include "student.hpp"
using namespace std;

int main()
{
  const Student st1 = Student("00001", "wangdamao", 89,98,83);  
  const Student st2 = Student("00002", "wangxiaoming", 89,89,97);

  st1.getMaxObj(st2).display();

  return 0;
}

st1.getMaxObj(st2).display(),我们先通过st1的getMaxobj()方法得到了一个总分较大的对象,该对象也是Student类对象,因此可以调用display()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值