招商网站建设方案,做美工用什么素材网站,免费店铺logo设计生成器,国际新闻最新消息十条摘抄坚持看完#xff0c;结尾有思维导图总结 这里写目录标题C语言和 C 的区别类的定义类的初认识类的内容访问限定符类的作用域类的实例化类中的 this 指针总结C语言和 C 的区别
C 的祖师爷除了在 C语言的基础上化简了一些复杂操作 更为重要的是#xff0c;两个语言实现的过程是… 坚持看完结尾有思维导图总结 这里写目录标题C语言和 C 的区别类的定义类的初认识类的内容访问限定符类的作用域类的实例化类中的 this 指针总结C语言和 C 的区别
C 的祖师爷除了在 C语言的基础上化简了一些复杂操作 更为重要的是两个语言实现的过程是不一样的 C 语言是一种面向过程的语言而 C 是一种面向对象的语言
如果是洗衣服 C 语言会这样洗 那盆子放水放衣服加洗衣粉手搓晾干 而 C 会先分析有哪些对象
会有 人 衣服 洗衣机 洗衣粉 通过这些对象的交互完成洗衣服 人只要做把衣服放进洗衣机加洗衣粉打开洗衣机就可以 不需要关注衣服是怎么洗的
类的定义
类的初认识
上面我们如果是用 C 语言来写就要定义一个盆子然后放水是一个函数 放衣服是一个函数加洗衣粉是一个函数手搓衣服是一个函数晾干是一个函数 然后一步步地走
但是 C 不同 他会把人 衣服 洗衣粉 洗衣机分别定义成一个个的类 人有哪些特性功能归到人这个类里面 衣服有哪些特性功能归到衣服这个类中 洗衣机有哪些特性功能归到洗衣机这个类中
我们很自然地联想到一个自定义的类型在 C语言中我们常使用结构体定义 struct 但是 在 C 语言里面结构体内部并不支持函数
然而在 C 中我们可以在结构体里头写函数了 这样于 c语言结构体类似但是不同的东西 我们把他叫做类 类的定义是这样的
class Name
{
//成员函数和成员变量
};// 注意分号类的内容
类中的内容可以分成两类一类是 成员变量 一类是成员函数 如果我们认识一个人我们能知道这个人是谁叫什么名字是什么性别 class Person
{
//成员函数
public:void personinfo(){cout _name _age _sex endl;}
// 成员变量
private:char* _name;int _age;char* _sex;
};这里的实现是声明和定义放在一起的 有时候类中声明和函数放在一起的情况编译器可能会把成员函数看做是内联函数
如果我们想要把声明和实现分离
在实现的位置一个是不要忘记头文件的应用 在引用完头文件后要说明实现的函数属于哪一个类这里是类的作用域的问题 声明则放在类里面
访问限定符
有一件奇怪的事情 为什么成员变量前面要加上 private 而 成员函数前面要加上 public 这里就设计到访问限定符的问题
我们都用过洗衣机也大概都知道怎么用洗衣机 就那几个按钮的事情对吧 我们不会为了使用洗衣机去研究洗衣机的结构
类也是这样除了设计者 使用的人只要会用成员函数就可以了并不会去关注成员变量有哪些
public 变式公共的 能够为外界调用 private 表示私人就是不能被类之外的操作访问但是类内的函数(成员函数)是可以访问的
那我们就能够调用 public 的函数来间接按照特定的方式访问 private 的成员
还有 一个访问限定符 叫 protected 因为是 简略说明 所以暂时不介绍
其中需要注意的是 class的默认访问权限为privatestruct为public(因为struct要兼容C) 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止 如果后面没有访问限定符作用域就到 } 即类结束。
而这种通过访问权限隐藏类的成员变量结构显示类的访问方式的做法就是封装
就好像是洗衣机内部被洗衣机外壳包起来我们看不到内部结构的方式就是封装 而封装是面向对象 的三大特性之一
类的作用域
之前在初识C 中我们说为了防止多个程序员使用同名变量同名函数 我们可以用不同的作用域来圈定哪些变量属于程序员 A ,哪些变量属于程序员 B
而当我们定义一个类的时候,会自动生成一个类的作用域 不同的类是可以使用同名函数和变量的使用类的作用域能够很好地应对这种情况 因为成员变量已经在类里面了不用再表明属于哪一个类 而当函数声明和实现分离时在实现函数的时候必须指明属于哪一个类防止实现的混淆
类的实例化
前面我们解决的是类的声明的问题 类的声明就好像把动物分成一个个种类比如像熊猫这是一类动物 但是其中的每一只熊猫都有自己的特征自己的名字等
这种就叫做实例化 在计算机中我们说类有 成员函数成员变量都是类的声明 而在使用中调用的类才是类的实例化 我们可以简单理解为为类开空间就是类的实例化
既然为类开空间了那就说明有空间大小 空间大小是如何计算呢? 尤其是一个类中有成员函数整个类大大小计算更加奇怪了
#define _CRT_SECURE_NO_WARNINGS 1
#includeiostream
using namespace std;class Date
{
public:void DateInit(Date date, int year 1, int month 1, int day 1);
private:int _year;int _month;int _day;
};void Date::DateInit(Date date,int year,int month,int day)
{date._year year;date._day day;date._month month;
}int main()
{Date d1;d1.DateInit(d1,2023,2,14);cout sizeof(d1) endl;return 0;
}我定义了一个日期类其中内部成员有年月日 通过计算大小发现 计算大小是 12 说明 ---- 内部只给内部成员开辟了空间但是没有给函数开辟空间 那函数的空间开辟到哪里去了呢
实际上类的空间开辟是这样的 事实上每一个成员虽然不同但是调用的成员函数传递的参数都是一样的 也就是说对于类的成员函数来说 每个类只要把成员函数需要的参数传给我就可以了
成员函数是不管你是哪一个成员 我们在观察一下对应的汇编代码 可以看到调用的是同一个函数 既然编译器都帮你对应的函数调用转换了和调用一个普通函数差不多 又何必开辟空间储存对应的函数指针甚至是整个函数栈帧呢答案是没有必要浪费这个空间
但是要注意的是如果实例化一个空类一个没有内容的类 他的空间大小是 1 用来占位
类中的 this 指针
在类的成员函数中我们可以这样写初始化函数
#define _CRT_SECURE_NO_WARNINGS 1
#includeiostreamusing namespace std;class Date
{
public:void Init(int year,int month,int day){_year year;_month month;_day day;}
private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(2023,2,16);return 0;
}在调试中我们能够看到 d1 被初始化为 2023 2 16
但是传参中我可是没有传递任何与 d1 相关的参数 只是之前的 d1.Init 指定了一下而已 成员函数是怎么样找到 d1 然后将 d1 初始化的呢
实际上编译器会自动帮我们传递一个 this 指针 的参数交给成员函数 这个 this 指针始终指向 调用这个成员函数的对象
比如我们 d1.Init 调用 Init 成员函数 编译器会把 this 指针传参 然后对应的成员 变成 this-成员 的解引用 但是我们不能直接把 this 指针当成一个参数写在函数上面 如果这样写编译器会传递自己在函数自动传参的 this 指针 但是 用户写的 this 这个形参的坑就没有人填了导致形参数量过多出现问题
总结 希望大家看完能够有所 如果有错误请指出我一定虚心改正 动动小手点赞 鼓励我输出更加优质的内容