首页 > 编程语言 >C++:this指针详解

C++:this指针详解

时间:2024-09-04 15:53:01浏览次数:7  
标签:ps int top C++ 详解 STDataType void 指针

目录

一、this指针

 二、C++和C语言实现Stack对比


一、this指针

• Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这里就要看到C++给了一个隐含的this指针解决这里的问题

• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针,比如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)

• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this- >_year = year;

• C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。

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;
};

运行下面两串代码,会发现两个代码虽然只差了一行代码,结果却差别很大

#include<iostream>
using namespace std;
class A
{
public:
 void Print()
 {
 cout << "A::Print()" << endl;
 }
private:
 int _a;
};
int main()
{
 A* p = nullptr;
 p->Print();
 return 0;
}
#include<iostream>
using namespace std;
class A
{
public:
 void Print()
 {
 cout << "A::Print()" << endl;
 cout << _a << endl;
 }
private:
 int _a;
};
int main()
{
 A* p = nullptr;
 p->Print();
 return 0;
}

     这里先说结果,第一串代码能正常运行,第二串代码会运行崩溃,第一串代码在调用了p->Print时这个函数,但是并没有对p这个空指针进行解引用,所以第一串代码能够正常运行,而第二串代码,再调用print函数之后,里面的_a实际是this->_a,对p进行了解引用,而p是空指针,而对于空指针的访问只有在运行时才会发生,编译器在编译阶段不会发现,所以不会程序报错,会在运行时崩溃。

     在C++中,this指针是一个隐含的指向当前对象的指针,它不是由程序员分配的,而是编译器自动创建并插入到每个成员函数的隐式参数列表中的,this指针位于函数调用帧的局部变量区,通常称为栈空间,用于存储函数执行时需要的临时数据和指向自身对象的数据,当函数被调用时,this 指针会被初始化为指向调用它的对象实例,这对于访问类的私有成员变量特别有,this 永远不会为空,除非是在静态成员函数或者非成员函数中,这时没有特定的对象关联。

 二、C++和C语言实现Stack对比

    面向对象三大特性:封装、继承、多态,下面的对比我们可以初步了解⼀下封装,通过下面两份代码对比,我们发现C++实现Stack形态上还是发生了挺多的变化,底层和逻辑上没啥变 化。

C实现stack代码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack
{
 STDataType* a;
 int top;
 int capacity;
}ST;
void STInit(ST* ps)
{
 assert(ps);
 ps->a = NULL;
 ps->top = 0;
 ps->capacity = 0;
}
void STDestroy(ST* ps)
{
 assert(ps);
 free(ps->a);
 ps->a = NULL;
 ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{
 assert(ps);
if (ps->top == ps->capacity)
 {
 int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
 STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * 
sizeof(STDataType));
 if (tmp == NULL)
 {
 perror("realloc fail");
 return;
 }
 ps->a = tmp;
 ps->capacity = newcapacity;
 }
 ps->a[ps->top] = x;
 ps->top++;
}
bool STEmpty(ST* ps)
{
 assert(ps);
 return ps->top == 0;
}
void STPop(ST* ps)
{
 assert(ps);
 assert(!STEmpty(ps));
 ps->top--;
}
STDataType STTop(ST* ps)
{
 assert(ps);
 assert(!STEmpty(ps));
 return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
 assert(ps);
return ps->top;
}
int main()
{
 ST s;
 STInit(&s);
 STPush(&s, 1);
 STPush(&s, 2);
 STPush(&s, 3);
 STPush(&s, 4);
 while (!STEmpty(&s))
 {
 printf("%d\n", STTop(&s));
 STPop(&s);
 }
 STDestroy(&s);
 return 0;
}

C++实现stack代码

#include<iostream>
using namespace std;
typedef int STDataType;
class Stack
{
public:
 // 成员函数 
 void Init(int n = 4)
 {
 _a = (STDataType*)malloc(sizeof(STDataType) * n);
 if (nullptr == _a)
 {
 perror("malloc申请空间失败");
 return;
 }
 _capacity = n;
 _top = 0;
 }
void Push(STDataType x)
 {
 if (_top == _capacity)
 {
 int newcapacity = _capacity * 2;
 STDataType* tmp = (STDataType*)realloc(_a, newcapacity * 
sizeof(STDataType));
 if (tmp == NULL)
 {
 perror("realloc fail");
 return;
 }
 _a = tmp;
 _capacity = newcapacity;
 }
 _a[_top++] = x;
 }
 void Pop()
 {
 assert(_top > 0);
 --_top;
 }
 bool Empty()
 {
 return _top == 0;
 }
 int Top()
 {
 assert(_top > 0);
 return _a[_top - 1];
 }
 void Destroy()
 {
 free(_a);
 _a = nullptr;
 _top = _capacity = 0;
 }
private:
// 成员变量 
 STDataType* _a;
 size_t _capacity;
 size_t _top;
};
int main()
{
 Stack s;
 s.Init();
 s.Push(1);
 s.Push(2);
 s.Push(3);
 s.Push(4);
 while (!s.Empty())
 {
 printf("%d\n", s.Top());
 s.Pop();
 }
 s.Destroy();
 return 0;
}

• C++中数据和函数都放到了类里面,通过访问限定符进行了限制,不能再随意通过对象直接修改数据,这是C++封装的一种体现,这个是最重要的变化,这里的封装的本质是一种更严格规范的管 理,避免出现乱访问修改的问题,当然封装不仅仅是这样的,我们后面还需要不断的去学习。

• C++中有一些相对方便的语法,比如 Init 给的缺省参数会方便很多,成员函数每次不需要传对象地 址,因为this指针隐含的传递了,方便了很多,使用类型不再需要typedef用类名就很方便。


      本篇关于this指针的内容就到这里了,希望对各位有帮助,如果有错误欢迎各位指出。

标签:ps,int,top,C++,详解,STDataType,void,指针
From: https://blog.csdn.net/2401_86551514/article/details/141854462

相关文章

  • 全志T527:详解全志T527性能评测,九鼎创展核心板开发板全面上市!
       T527系列芯片是全志旗下的高性能八核的SOC,适用于收银结算、工业应用和汽车电子。该芯片系列集成了八核Cortex-A55CPU,一个HiFi4DSP,2tops的NPU,G57MC1GPU,32位DDR3/DDR3L/DDR4/LPDDR3/LPDDR4/LPDDR4XDRAM,高速接口(PCle2.1和USB3.1)、汽车接口(CAN)、多视频输出接口(2*R......
  • 代码执行详解
    代码执行定义        应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。代码执行的原理        应用程序本身过滤不严,用户可以通过请求将代码(代码字符串)注入到应用中执行。代码执行相......
  • sar -d 命令详解
    sar-d是sar命令中的一个选项,用于显示磁盘I/O统计信息。它提供有关磁盘设备读写操作的详细信息,有助于监控磁盘性能和识别潜在的I/O瓶颈。sar-d命令详解基本用法sar-d[interval][count]interval:指定数据收集的时间间隔(秒)。count:指定收集的数据条数。如果不提......
  • C端的两板斧:C++与C#
      开篇,先为大家介绍一下家乡里面的两种方言:土白话(粤语)和土客家话。这里都给了个土的前缀,并没有任何贬义的意思,这个土是本土的土,指的是粤语和客家话结合了当地的风俗民情,使得语言表达更简洁明了,往往一个语气词,就能在不同的场景,有很多不同的理解,比如说”丢”(这里是第二声......
  • Linux之curl详解
    curl是一个非常强大的命令行工具,用于发送和接收数据,支持多种协议,如HTTP、HTTPS、FTP等。它被广泛用于测试、调试Web接口以及自动化脚本中。下面是对curl的详细解释,包括其基本用法和一些高级特性。基本用法发送HTTPGET请求bashcurlhttp://example.com这个命令会......
  • STM32的窗口看门狗详解及案例(基于HAL库)
    目录一、引言二、窗口看门狗的工作原理1.基本概念2.功能描述3.窗口值和计数器初始值三、STM32F429HAL库中窗口看门狗的配置步骤1.开启时钟2.初始化窗口看门狗 3.开启早期唤醒中断4.喂狗操作 四、窗口看门狗的应用场景 1.防止软件死锁2.检测外部干扰3.提高......
  • C++复习day02
    一、库函数的模拟实现1.memcpy的使用和模拟首先先来了解一下memcpy函数的作用是什么?void*memcpy(void*destination,constvoid*source,size_tnum);函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。这个函数在遇到‘\0......
  • 1.18 标识解析体系详解
    今天讲解了系统集成项目管理工程师教程视频课程(第3版)所涉及的标识解析体系相关的考试知识点,想通过考试的朋友可以点击链接,看完整版。......
  • c++ string类 重载实现(续)9月3日
    #include<iostream>#include<string>#include<cstring>classMystring{ private: intlen; char*str; public: Mystring() { str=nullptr; len=0; } Mystring(constchar*s) { len=strlen(s); str=newchar[len+1]; strcpy(s......
  • 详解ISP代理与住宅代理的主要区别
    在互联网的世界里,代理IP扮演着重要的角色。无论是为了保护隐私,还是为了进行市场调研,代理IP的应用场景都十分广泛。而在代理IP中,ISP代理和住宅代理是两种常见的类型。今天,我们就来聊聊这两种代理的主要区别,看看它们各自的优势和适用场景。什么是ISP代理?ISP代理,全称为互联网服......