【C++】第四节—类和对象(this指针、C++实现的Stack)
i,好久不见,我是云边有个稻草人,偶尔中二的C++领域博主与你分享专业知识!U·ェ·U

正文开始——
一、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 指针。
#include<iostream>using namespace std;//编译器自己会加上this,我们不必加上class Date{public://void Init(Date* const this, int year, int month, int day)void Init(int year, int month, int day){//this->_year = year;_year = year;_month = month;_day = day;}//void Print(Date* const this)void Print(){//this = nullptr;this不能被修改,但是this指向的内容可以被修改cout << this->_year << '/' << _month << '/' << _day << endl;}private://声明int _year;int _month;int _day;};//定义int year;int main(){Date d1;Date d2;//d1.Init(&d1,2024,9,20)d1.Init(2024, 9, 20);//d2.Init(&d2,2024,9,22)d2.Init(2024, 9, 22);//d1.Print(&d1);d1.Print();//d2.Print(&d2);d2.Print();return 0;}
【 习题三道】
1.下⾯程序编译运⾏结果是(C)
A、编译报错 B、运⾏崩溃 C、正常运⾏
#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;}
2.下⾯程序编译运⾏结果是(B)
A、编译报错 B、运⾏崩溃 C、正常运⾏
#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就相当于call Print函数的地址,虽然有指针解引用的形态但这不是真正的解引用。


3. this指针存在内存哪个区域的 (A)
A. 栈 B.堆 C.静态区 D.常量区 E.对象里面
this是一个隐含的形参。局部变量,形参存在函数栈帧里面。
二、C++和C语言实现Stack对比
面向对象三大特性:封装、继承、多态,下面我们来初步了解一下封装。
-
C++中数据和函数都放在了类里面,通过访问限定符进行了限制,不能再随意通过对象进行修改数据,这是C++封装的一种体现,这个是最重要的变化,这里的封装的本质是一种更严格规范的管理,避免出现乱访问修改的问题。封装不仅仅是这样,后面需要我们不断地学习。
-
C++中有一些相对方便的语法,比如:Init给的缺省参数会方便很多,成员函数每次不需要传对象地址,因为this指针隐含的传递了,方便了很多,使用类型不再需要typedef直接用类名就很方便。
-
后面我们用STL中的适配器实现的Stack可以感受下C++的魅力。
【C实现Stack】
C实现Stack#include<stdio.h>#include<assert.h>#include<stdbool.h>#include<stdlib.h>typedef int STDataType;typedef struct Stack{STDataType* a;int top;int capacity;}ST;void STInit(ST* ps){ps->a = NULL;ps->top = ps->capacity = 0;}void STDestroy(ST* ps){assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;}void STPush(ST* ps, int x){assert(ps);//判断空间是否充足if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->a, newCapacity * sizeof(int));if (tmp == NULL){perror("realloc file!");return;}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top++] = x;}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 main(){ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);while (!STEmpty(&s)){printf("%d ", STTop(&s));STPop(&s);}STDestroy(&s);return 0;}
【C++实现Stack】 来都来了,不得敲一下

C++实现Stack#include<iostream>#include<assert.h>using namespace std;class Stack{typedef int STDataType;public://成员函数void Init(int n = 4){_a = (STDataType*)malloc(sizeof(STDataType) * n);_top = 0;_capacity = n;}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;int _top;int _capacity;};int main(){Stack s;s.Init();s.Push(1);s.Push(2);s.Push(3);s.Push(4);while (!s.Empty()){cout<<s.Top<<" ";s.Pop();}s.Destroy();return 0;}
更多推荐
所有评论(0)