先说说类
类有两种定义方式:
1. 声明和定义全部放在类中,需要注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
2. 声明放在.h文件中,类的定义放在.cpp文件中
类的访问和封装
问题:C++中struct和class的区别是什么?
解答:C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用来定义类。 和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式 是private。
面向对象的三大特性:封装、继承、多态。
在类和对象阶段,我们只研究类的封装特性,那什么是封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。 封装本质上是一种管理
类的实例化:
1. 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它
2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占 用物理空间
类对象模型
这里需要注意的是有两点比较重要
第一是计算类对象的大小
第二是类对象的存储方式
解决第一个问题,首先要清楚第二个问题:
一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。
接下来计算大小就根据结构体内存对齐的规则来计算,这里可以回想一下C语言内容中提出的几个问题:
1. 结构体怎么对齐? 为什么要进行内存对齐
2. 如何让结构体按照指定的对齐参数进行对齐
3. 如何知道结构体中某个成员相对于结构体起始位置的偏移量
4. 什么是大小端?如何测试某台机器是大端还是小端,有没有遇到过要考虑大小端的场景
内存对齐:
C语言深度解析之六:自定义类型详解(结构体+枚举+联合)_何以过春秋的博客-CSDN博客
大小端:
C语言深度解析之一:数据存储_何以过春秋的博客-CSDN博客
说起this指针,其实就是从C++与C语言之间不同的语法特性出发的。
每一个对象都能通过 this 指针来访问自己的地址:this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。他的类型是* const
友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。
同时,静态成员函数也没有this指针。
为了引入this指针,我们看一个例子
- class Date
- {
- public :
- void Display ()
- {
- cout <<_year<< "-" <<_month << "-"<< _day <
- }
- //void SetDate(Date* this,int year , int month , int day)
- void SetDate(int year , int month , int day)
- {
- _year = year;
- //this->_year = year;
- _month = month;
- //this->_month = month;
- _day = day;
- //this->_day = day;
- }
- private :
- int _year ; // 年
- int _month ; // 月
- int _day ; // 日
- };
-
- int main()
- {
- Date d1;
- Date d2;
- d1.Init(2021,10,8);
- //d1.Init(&d1,2021,10,8);
-
- d2.Init(2022,10,8);
- d1.Display();
- d2.Display();
- return 0;
- }
Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,如果创建了d1,d2两个对象,那当d1调用SetDate函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
所以这里实际上有一个this指针,它指向当前对象,通过它可以访问当前对象的所有成员。
我们在调用成员函数后,编译器其实会再传一个参数进去,这个参数为当前对象的地址:
d1.Init(&d1,2021,10,8);
而成员函数本质上是这样:
- void SetDate(Date* this,int year , int month , int day)
- {
- this->_year = year;
- this->_month = month;
- this->_day = day;
- }
解释完this指针后,来看下面这个程序:
- class A
- {
- public:
- void show()
- {
- cout<<"show()"<
- }
- void Print()
- {
- cout<<_a<
- }
-
- void PrintA()
- {
- cout<<"PrintA()"<
- }
- private:
- int _a;
- };
- int main()
- {
- A* p = nullptr;
- p->show();
- p->Print();
- p->PrintA();
- return 0;
- }
三次调用函数这个程序的结果是什么?
第一行第三行正常运行,第二场直接崩溃
这里还引出了一个面试问答:this指针可以为空吗?
最后谈一个问题:this指针存在哪里?
不是存在对象中哦
this指针是形参,形参和函数中的局部变量都是存在函数栈帧里面的,所以this指针是存在栈区的,vs下this指针是通过寄存器ecx传递的
-
相关阅读:
yolov1算法思想流程简单讲解概述————(究极简单的讲述和理解)
值传递还是引用传递(By Value or By Reference)
【机器学习】MS_MARCO_Web_Search解析说明
Python学习打卡:day08
postgresql逻辑备份工具pg_dump和pg_resotre学习
近视是怎样形成的?
(web前端网页制作课作业)使用HTML+CSS制作非物质文化遗产专题网页设计与实现
集合框架----源码解读LikedeHashSet篇
Docker中使用Tomcat并部署war工程
代码随想录算法训练营第五十二天|
-
原文地址:https://blog.csdn.net/yzy521wjm/article/details/126207829