C++:this指针详解

敲代码的奥豆 2024-09-06 16:35:02 阅读 93

目录

一、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指针。

<code>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指针的内容就到这里了,希望对各位有帮助,如果有错误欢迎各位指出。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。