> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:掌握类的引用和定义,熟悉类成员函数的this指针。

> 毒鸡汤:励志是给人快乐,激励是给人痛苦。
> 望小伙伴们点赞收藏✨加关注哟

前言

还没找到对象的小伙伴们,从今天开始就有对象了。为什么这么说捏,因为呀C嘎嘎已经进入了类和对象,开心的小伙伴们举个手手,嘻嘻嘻。从今天开始我们就需要喜新厌旧了,对以前的C语言看都不想看,到时候你就会觉得用C嘎嘎是真的爽,可能是有对象了吧。闲话少谈,进入今天的课题–《类和对象上》。

主体

咱们从五大板块学习,类的引入,类的定义,类的访问限定符及封装,类的实例化类成员函数的this指针。这里需要简单说一下C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。




类的引入

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数。上面结构体的定义,在C++中更喜欢用class来代替。

简单看一下面代码:



类的定义

上面的模块是引入类,那c++中类是如何定义的捏,

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。

咱们看下面图解:



类的定义第一种方法

声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
联函数处理。

图解如下:



类的定义第二种方法

类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

图解如下:



类的访问限定符及封装

在定义类时我们看到了public这个关键字,大家可能看不懂,其实这个关键字在c++是一个类的访问限定符,C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

看下面的访问限定符:



具体有啥区别捏:

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. 如果后面没有访问限定符,作用域就到 } 即类结束。
  5. class的默认访问权限为private,struct为public(因为struct要兼容C)

类的实例化类成员函数的this指针

既然定义了类,必然有它们的作用域:类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::作用域操作符指明成员属于哪个类域。

看图解:



既然定义了类,必然占用内存:一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。

咱们看物理图:



既然定义了类,那类存储又是如何捏:每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。那么如何解决呢?

看图解:



this指针

咱们先看一段代码:



对于上述类,有这样的一个问题:
Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

注意:

  1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。

  2. 只能在“成员函数”的内部使用

  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

  4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

看图解:



用c++实现Stack

如果还有人不会用C语言实现栈的小伙伴们先看下面这篇博客

CSDN栈的实现

#includeusing namespace std;typedef int DataType;class Stack{public:void Init(){_array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = 3;_size = 0;}void Push(DataType data){CheckCapacity();_array[_size] = data;_size++;}void Pop(){if (Empty())return;_size--;}DataType Top() { return _array[_size - 1]; }int Empty() { return 0 == _size; }int Size() { return _size; }void Destroy(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:void CheckCapacity(){if (_size == _capacity){int newcapacity = _capacity * 2;DataType* temp = (DataType*)realloc(_array, newcapacity *sizeof(DataType));if (temp == NULL){perror("realloc申请空间失败!!!");return;}_array = temp;_capacity = newcapacity;}}private:DataType* _array;int _capacity;int _size;};int main(){Stack s;s.Init();s.Push(1);s.Push(2);s.Push(3);s.Push(4);printf("%d\n", s.Top());printf("%d\n", s.Size());s.Pop();s.Pop();printf("%d\n", s.Top());printf("%d\n", s.Size());s.Destroy();return 0;}

结束语

今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小说手给博主一键三连,有你们的支持是我最大的动力,回见。