Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。
0. 初识类
我们先来看看C语言解决一个问题的过程。
假设有以下这个场景:你需要把大象放进冰箱,你需要做哪几步?
1.打开冰箱门
2.拿起大象
3.把大象放进冰箱
4.关上冰箱门
这是用C语言解决一个问题的过程,那么来看下C++是怎么解决这个问题的.
在C++当中,把每一个用到的对象抽离了出来,例如这里的:你,冰箱,大象都会被归类为一个个对象,而你们会有自己的属性,也就是自己的动作,而此时你就不需要去关注,人是怎么把大象拿起,怎么把大象放进冰箱,你只需要关心一个个对象之间的逻辑就可以了.
1.类的引入
先来看看我们之前最熟悉的C语言中的Struct在C++中他被升级成了类.
struct cdate{ int _date; int _month; int _year; };
这是在c语言中我们就会使用的方法,他被升级成类之后有了什么变化呢?
在一个结构体里可以定义函数了:
#include<iostream> using namespace std; struct cdate{ int _date; int _month; int _year; int max(int a,int b) { return a>b?a:b; } }; int main() { cdate c; cout<<c.max(5,3); }
这在c中是不可以的,不信的uu们可以去试试(要将文件名后缀改成C哦,不然编译器会以C++的标准来运行)
定义一个Struct的时候再也不用写Struct了.
这个直接看上面的cdate即可.
但在C++中更喜欢用Class来替换上面的struct,所以我们一般将代码写成这样:(关于public是什么意思接下来会解释,这里直接写就好啦)
#include<iostream> using namespace std; class cdate{ public: int _date; int _month; int _year; int max(int a,int b) { return a>b?a:b; } }; int main() { cdate c; cout<<c.max(5,3); }
这就是一个类的大概状态啦,接下来我们将更详细的解释一下类的各部分.
2.类的定义
class classname { //类体 };
class为定义类的关键字,classname为类的名字,{}中为类的主体,与结构体相同,结束时也需要加上一个;
所以类的组成由两个部分组成:类体与类名
类体中的内容称为类的成员:
1. 类的变量称为类的属性或成员变量 1. 类中的函数称为类的方法或者成员函数
类的两种定义方式:
类定义了一个新的作用域,仅能在这个作用域里访问其private成员
与C相同定义一个函数的时候也可以采用声明与定义放在同一个地方的方式:
class max{ public: int max(int a,int b) { return a>b?a:b; } };
例如这里的max函数,但更推荐采用下面这种方式,将函数声明放在类中,定义写在这个类的外面(也可以解释为将类的声明放在头文件当中,类的具体定义放到源文件当中,这样做的好处和c一样),但注意,这样写要在定义处加上一个**类作用声明符**:
class cdate{ public: int max(int a,int b); }; int cdate::max(int a,int b) { return a>b?a:b; }
其中**cdate:😗*为类作用声明符.
成员变量的命名规范:
看看这个函数:
class student { public: void inname(int score) { score = score; } void print() { cout << score; } private: int score = 0; }; int main() { student s1; s1.inname(80); s1.print();//80 }
这里定义了一个简单的student对象,对他的分数进行输入输出(一样private马上就会讲是什么东西),我们观察inname中的这段代码:
score=score
这里执行的结果本意是想要将外部传进的参数放进这个s1的score当中,但似乎外部的参数与内部的属性相互重合了.所以我们一般将内部属性命名添加一个_,来表示是内部的属性(不同的工作环境命名规范不同,但要有这么个意识)
所以这段代码应该写成这样:
class student{ public: void inname(int score) { _score=score; } string name; void print() { cout<<_score; } private: int _score=0; }; int main() { student s1; s1.inname(80); s1.print();//80 }
3.类的访问限定符与封装
这里介绍以下上文提到的private,public,protected.
1.在类中访问权限作用域一直到下一个访问权限符出现为止
2.public修饰的成员在类外可以直接被访问
3.private与protected(他们虽然有一些细微的差别,但先认为他们是一样的)修饰的成员在类外无法被访问,通常通过调用Public里的对应函数来进行访问.
面试题:C++中的struct与class的差别是什么
C++需要兼容C语言,所以**C++中的struct可以当成结构体用,同时也可以用来定义类.**区别是:struct的默认权限是public(为了兼容C语言)而class的默认权限是private
这三个限定符的作用是什么?
看看你面前的计算机,平常需要将其开机要做的就是按下面前的电源键,而不需要关心他的电路是如何运作的.这就是将电路进行了**private**,而将开机按钮的权限为 public,你可以直接通过这个public的方法去让他开机.也就是作为一个用户仅需要关注他能实现的功能而不需要去关注他的实现细节
在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用
4.类的实例化
下面是一个类的定义(也可以叫模板,这里的模板与C++中的模板没有任何关系)
class student{ public: void inname(int score) { _score=score; } string name; void print() { cout<<_score; } private: int _score=0; };
可以把这个模板看作一个设计图,它本身不占空间,只是设计出了这个房子的构成.但你用这个设计图去造出一个个房子(实例化一个个对象).他就占空间了.
class student{ public: void inname(int score) { _score=score; } string name; void print() { cout<<_score; } private: int _score=0; }; int main() { student s1; s1.inname(80); s1.print();//80 }
类的空间计算
还是那个设计图的例子,我们可以将一个类的函数比作这个小区的各种公共设施,每一个家庭都要用到电梯,但我需要为每一个家庭都装上一个电梯嘛?显然是不需要的,也就是说一个类的函数是公用的,他们被存储在了公共代码区.而每一个家庭里的设施虽然都是从模板里设计出来的,但是会有一些差异,所以我们需要保存每一个对象的属性.
所以类的存储模型就是这样:
所以计算一个对象的所占内存大小的时候仅需计算成员属性的内存大小(其符合结构体内存对齐的规则)
class student{ public: void inname(int score) { _score=score; } void print() { cout<<_score; } private: int _score=0; char _name; }; int main() { student s1; cout<<sizeof(s1);//8 }