【直击招聘C++】2.5 this指针

news/2024/11/27 4:53:41/

2.5 this指针

  • 一、要点归纳
    • 1.什么是this指针
    • 2.this指针的深入讨论
      • 程序1
      • 程序2
    • 3.类成员函数返回对象和返回对象引用的区别
  • 二、面试真题解析
    • 面试题1
    • 面试题2

一、要点归纳

1.什么是this指针

  this指针是隐含于每一个类对象的特殊指针,该指针值是一个正在被某个成员函数操作的对象的地址。
  this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来每个对象都拥有自己的成员函数,所以this指针在成员函数开始执行钱构造,在成员函数执行结束后清除。只有获得一个对象后才能通过对象使用this指针,而且this指针只有在成员函数中才有定义。
例如有以下程序:

#include <iostream>class Test
{int n;public:Test() {}Test(int m) { n = m; }void addvalue(int m){Test s1;s1.n = n + m;*this = s1;}void disp() { std::cout << "n=" << n << std::endl; }
};int main()
{Test s(10);s.disp();s.addvalue(5);s.disp();return 0;
}

程序的执行结果如下:

n=10
n=15

Test类中定义了一个addvalue的非静态成员函数,在调用它时需要写成:

Test s;
s.addvalue(5);

也就是说需要告诉系统是将s对象的私有数据成员n增大5,而不是其他对象。它实际上相当于以下函数调用。

addvalue(&s,5);

即将类对象的地址作为第1个参数传递给了函数。addvalue函数的原型相当于:

void addvalue(Test * this, int m);

该函数的第1个参数是指向该类对象的一个指针,即this指针。在定义该成员函数时并没有看到这样一个参数,因为这个参数是系统隐含的。在成员函数的定义体中可以通过this访问这个地址参数。如果不用this指针,该成员函数等同于如下代码:

void addvalue(int m)
{n+=m;
}

this指针只能用在类的非静态成员函数中使用,它指向该成员函数被调用的对象。静态成员函数没有this指针,因为类只有一个静态成员函数的副本,所以使用this指针没有什么意义。

2.this指针的深入讨论

程序1

class A
{int n;public:A() { n = 1; }void fun() { std::cout << "n=" << this->n << std::endl; }
};
void test02()
{A *p = NULL;// p->fun();
}

上述程序中A的成员函数放在代码区,对应有一个地址,在链接时将调用fun函数的地方用这个地址代替,并传递this指针。类Test的对象指针p为NULL,所以this指向没有意义的实例,在执行p->fun()时由于访问this->n导致程序崩溃。

程序2

class B
{int n;public:B() { n = 1; }void fun() { std::cout << "fun" << std::endl; }
};
void test03()
{B *p = NULL;p->fun();
}

上述程序可以正确执行,并输出fun。fun函数中并没有this指针,所以不存在链接问题,不会报错。如果在fun函数中访问this指针,或者访问任何非静态数据成员都会导致程序崩溃。

3.类成员函数返回对象和返回对象引用的区别

下面通过一个实例说明返回对象和返回对象引用的类成员函数的区别。

class C
{int m;public:C() : m(1) {} // 默认构造函数~C() {}       // 析构函数C fun1(){std::cout << "m=" << m << std::endl;return *this;}C &fun2(){std::cout << "m=" << m << std::endl;return *this;}void set(int x) { m = x; }void display() { std::cout << "m=" << m << std::endl; }
};
void test04()
{std::cout << "===返回对象===" << std::endl;C c1;c1.fun1().set(2);c1.display();std::cout << "===返回对象引用===" << std::endl;C c2;c2.fun2().set(2);c2.display();
}

在上述程序中类C有fun1()和fun2()两个公有成员函数,其中 C fun1()是返回C对象的成员函数,而C& fun2()是返回C对象引用的成员函数,两个成员函数的函数体相同。执行test04函数的主要语句过程如下:

  • C c1语句调用默认构造函数创建c1
  • c1.fun1().set(2)语句先执行c1.fun1(),输出m=1,返回当前对象,并调用拷贝构造函数创建一个临时对象,再通过这个临时对象调用set(2),将这个临时对象的m修改为2,该语句执行完毕。调用析构函数销毁这个临时对象,而c1没有发生任何改变。
  • c1.display()语句输出m=1
  • C c2语句调用默认构造函数创建c2
  • c2.fun2().set(2)语句首先执行c2.fun2(),输出“m=1”,由于fun2()函数类型的对象引用,其执行结果为对象c2,再调用set(2),等同于c2.set(2),将对象c2的m修改为2。
  • c2.display()输出m=2
  • test04函数执行完毕,调用两次析构函数销毁对象c2和c1。

二、面试真题解析

面试题1

【面试题】下面程序段中包含4个函数,其中具有隐含this指针的是(f4)

int f1();
class  T
{public:static int f2();private:friend int f3();protected:int f4();
};

【答】类中的静态成员函数和友元函数不含this指针,普通非成员函数也不含this指针。

面试题2

【面试题】在成员函数中return *this和return this有何不同?
【答】对于类A,其成员函数中return *this返回的是当前对象的副本或者本身(若成员函数的返回类型为A,则是返回副本;若成员函数的返回类型为A&,则是返回本身),而return this返回当前对象的地址(指向当前对象的指针)。


http://www.ppmy.cn/news/23972.html

相关文章

C++类和对象(下)

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f38a;每篇一句&#xff1a; 图片来源 I do not believe in taking the right decision. I take a decision and make it right. 我不相信什么正确的决定。我都是先做决定&#xff0c;然后把…

零代码做分析报表的bi软件才是好软件

有些数据分析软件对IT的依赖比较重&#xff0c;在制作报表的过程中需要用到SQL&#xff0c;这就导致了IT人员懂技术不懂业务&#xff0c;业务人员懂业务不懂技术&#xff0c;数据分析做来做去总是差点什么的局面。要是遇到了IT部门相对较弱的情况&#xff0c;还会加重IT负担&am…

基于C#制作一个飞机大战小游戏

此文主要基于C#制作一个飞机大战游戏&#xff0c;重温经典的同时亦可学习。 实现流程1、创建项目2、界面绘制3、我方飞机4、敌方飞机5、子弹及碰撞检测实现流程 1、创建项目 打开Visual Studio&#xff0c;右侧选择创建新项目。 搜索框输入winform&#xff0c;选择windows窗体…

GPR后期功能整理

基金本子写得太困难了&#xff0c;学术水平不够&#xff0c;好的想法未想到好的科学问题&#xff0c;难以下笔。和龙工沟通后&#xff0c;得到了大量impulse radar的数据&#xff0c;后期需要进行分析&#xff0c;从而能让GPR智能识别走得更远。从数据解译角度&#xff0c;找到…

前端JavaScript获取图片文件的真实格式

常见方式判断图片格式 当我们进行前端开发&#xff0c;需要处理图片上传功能&#xff0c;针对图片格式做判断时&#xff0c;常规的方法都是使用文件后缀名来判断&#xff0c;如下代码所示&#xff1a; input.addEventListener(change, (e) > {const file e.target.files[…

函数栈帧的创建和销毁——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰来为大家介绍一个知识点——函数栈帧的创建和销毁。其实这个知识点&#xff0c;我们很早之前就要讲&#xff0c;但是因为我的一系列原因&#xff0c;才一直拖到了现在&#xff0c;那么&#xff0c;话不多说&#xff0c;让我们一起…

canal使用说明:MySQL、Redis实时数据同步

1. canal简介 canal是阿里开源的数据同步工具&#xff0c;基于bin log可以将数据库同步到其他各类数据库中&#xff0c;目标数据库支持mysql,postgresql,oracle,redis,MQ,ES等 canal分成服务端deployer和客户端adapter&#xff0c;我们可以部署多个&#xff0c;同时为了方便管…

状态机设计中的关键技术

⭐本专栏针对FPGA进行入门学习&#xff0c;从数电中常见的逻辑代数讲起&#xff0c;结合Verilog HDL语言学习与仿真&#xff0c;主要对组合逻辑电路与时序逻辑电路进行分析与设计&#xff0c;对状态机FSM进行剖析与建模。 &#x1f525;文章和代码已归档至【Github仓库&#xf…