C++类和对象你真的听懂了吗?来,看完这篇保姆级类和对象教程,保证你在学校杀疯(2)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

strcpy(_gender, gender);
_age = age;
}

void PrintStudentInfo()
{
cout<<_name<<" “<<_gender<<” "<<_age<<endl;
}
//以上两个函数就是声明和定义放在一起
char _name[20];
char _gender[3];
int _age;
};


2.声明和定义分离(声明.h定义.cpp)


 以下为了方便演示就在类外面定义的,大家了解就行,注意要加上类的作用域Student::



struct Student
{
void InitStudentInfo(const char* name, const char* gender, int age);
void PrintStudentInfo();
//以上两个函数就是声明
char _name[20];
char _gender[3];
int _age;
};
void Student::InitStudentInfo(const char* name, const char* gender, int age)
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void Student::PrintStudentInfo()
{
cout<<_name<<" “<<_gender<<” "<<_age<<endl;
}


以上两种方式各有好处,但是一般在项目工程中我们一般采用第二种。 


### 4.类的访问限定符以及封装


#### 4.1访问限定符



C++
实现封装的方式:
**用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其**
**接口提供给外部的用户使用**
。 


![](https://img-blog.csdnimg.cn/a465e8d16edb4102a6ee9f9f52a0f46b.png)


 访问限定符说明: 



1. public
修饰的成员在类外可以直接被访问 


2. protected
和
private
修饰的成员在类外不能直接被访问
(
此处
protected
和
private
是类似的
) 


3. 
访问权限
**作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止** 


4. class
的默认访问权限为
private
,
struct
为
public(
因为
struct
要兼容
C) 


 注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别 
 

![](https://img-blog.csdnimg.cn/55940ed1cd664d608756c047783ff1f9.png)


#### 4.2经典面试问题



**【面试题】** 


**问题:**
**C++**
**中**
**struct**
**和**
**class**
**的区别是什么?** 


解答:
C++
需要兼容
C
语言,所以
C++
中
struct
可以当成结构体去使用。另外
C++
中
struct
还可以用来定义类。 


和
class
是定义类是一样的,区别是
struct
的成员默认访问方式是
public
,
class
是
struct
的成员默认访问方式 


是
private
。

#### 4.3封装



面向对象的三大特性:
**封装、继承、多态**
。 


在类和对象阶段,我们只研究类的封装特性,那什么是封装呢? 


> 
> 
> *封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。* 
> 
> 


### 5.类的作用域



**类定义了一个新的作用域**
,类的所有成员都在类的作用域中
**。**
在类体外定义成员,需要使用
 :: 
作用域解析符指明成员属于哪个类域。 



struct Student
{
void InitStudentInfo(const char* name, const char* gender, int age);
void PrintStudentInfo();
char _name[20];
char _gender[3];
int _age;
};
void Student::InitStudentInfo(const char* name, const char* gender, int age)//类的作用域
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void Student::PrintStudentInfo()//使用了类的作用域
{
cout<<_name<<" “<<_gender<<” "<<_age<<endl;
}


### 6.类的实例化



*用类类型创建对象的过程,称为类的实例化*


*1.类只是一个模型,如果不实例化,那么就没有实际分配内存空间来储存它*


*2.一个类呢是可以实例话出多个对象的,实例化的对象才会真正的分配到物理空间,储存类成员变量*


*3.打个比方将实例化对象比作大桥,那么类就像是设计图纸(并没有实体建筑的存在),靠着图纸才能造出一个个桥梁*


![](https://img-blog.csdnimg.cn/86b788051f224273bb96c08b0d081899.png)



 ![](https://img-blog.csdnimg.cn/cf749e49492642df8909fd8ece769380.png)


###  7.类对象模型


#### 7.1计算类的大小



问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小? 


在类中只保存成员变量大小,而函数是放在代码公共区域的。


 我们可以通过下面的不同类的大小来分析 



// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有—空类
class A3
{};



sizeof(A1) : 
**\_4\_**
 sizeof(A2) : 
**\_1\_**
sizeof(A3) : 
**\_1\_**



 有的同学可能就会有疑问,你不是说 
 ***只保存成员变量大小吗***,为啥A2和A3是1 
 

 这就是因为虽然A2和A3没有任何成员变量,但是他们需要有一个空间,来证明他们是存在的,如果没有任何空间分配给他们的话,那岂不是不存在这个类了。所以空类要分到 
 ***一个字节***的空间 
 
#### 7.2结构体内存对齐规则



 我们在学习c语言的时候已经学习了结构体的内存对齐规则, 
 ***类的大小计算规则和结构体是一样的***


1. 
第一个成员在与结构体偏移量为
0
的地址处。 


2. 
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。



注意:对齐数
 = 
编译器默认的一个对齐数 与 该成员大小的较小值。 


VS
中默认的对齐数为
8 


3. 
结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。 


4. 
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 


所有最大对齐数(含嵌套结构体的对齐数)的整数倍。 


### 8.this指针


#### 8.1this指针的引出


我们先用日期类来举一个例子:



class Date
{
public :
void Display ()
{
cout <<_year<< “-” <<_month << “-”<< _day <<endl;
}

void SetDate(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};
int main()
{
Date d1, d2;
d1.SetDate(2018,5,1);
d2.SetDate(2018,7,1);
d1.Display();
d2.Display();
return 0;
}



对于上述类,有这样的一个问题:



Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,那当s1调用SetDate函数时,该函数是如何知道应该设置s1对象,而不是设置s2对象呢?




C++中通过引入this指针解决该问题
,即:
**C++**
**编译器给每个**
**“**
**非静态的成员函数**
**“**
**增加了一个隐藏的指针参** 
**数,让该指针指向当前对象**
**(**
**函数运行时调用该函数的对象**
**)**
**,在函数体中所有成员变量的操作,都是通过该** 
**指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成**
。


也就是说编译器会增加一个
隐藏的参数


![](https://img-blog.csdnimg.cn/ff77b39b527d4117aa6faed81cf2f6ee.png)

这里要注意哦




![img](https://img-blog.csdnimg.cn/img_convert/2a89dbab2d69f9a4d5756a7c31ab39d2.png)
![img](https://img-blog.csdnimg.cn/img_convert/7fe99bf84696300fabc90c455f64f64b.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**

完成**
。


也就是说编译器会增加一个
隐藏的参数


![](https://img-blog.csdnimg.cn/ff77b39b527d4117aa6faed81cf2f6ee.png)

这里要注意哦




[外链图片转存中...(img-8YbuodCx-1715736868452)]
[外链图片转存中...(img-IB44eG7m-1715736868453)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值