目录
面向过程和面向对象
类
类是什么?
类的定义
1.声明和定义都放在类中
2.声明和定义分离
类的访问限定符
类的封装
类的作用域
类的实例化
类对象存储
结构体内存对齐规则
面向过程和面向对象
c语言是面向过程的
c++是面向对象的
怎么理解?
面向过程,我们用抖音有各种功能,最主要的是发视频和看视频。开发功能 发视频和看视频这两个行为是面向过程的。
面向对象,则是发视频的作者,和看视频的读者。根据这两个群体,来开发功能。就像我们大众是读者,我们不止可以刷视频还可以看直播,还可以点赞关注,这些功能都是放在读者类的。而对于作者发视频,看数据这些功能是放到作者类的。这就是面向对象。
所以说面向对象是较为宏观的,面向过程则就是较微观的。把对应的过程封装到对应的对象
类
类是什么?
我们在c语言里学过结构体 struct。但是在c语言中struct中只能定义变量。
而在c++以后有了面向对象的说法,所以类(对象)出现了他也是struct同时也可以用class(常用)。但不同点是类中是可以定义函数(过程)的。
类的定义
class className
{
//类体:由成员变量和成员函数组成
}; //注意后面的分号
这是类的写法和struct一样。
1.声明和定义都放在类中
将函数的定义和声明都放在类中
2.声明和定义分离
在头文件中将函数声明
在源文件中对函数的实现。
注意:定义和声明分离时要指定出是在哪一个类中
类的访问限定符
c++实现封装的方式:用类把对象的属性(变量)和方法(函数)都放到类中。然后再用访问限定符设置权限,选择性的把部分接口提供给用户。就像淘宝你可以改你自己店铺的图片,但你影响不了网页的整体布局。由权限决定的。
【限定符说明】
1.public里的接口外部可以用。
2.protected 和 private 的接口外部不能使用,区别在于 子类中能使用的是protected,不能使用的是private。
3.class 的默认限定符是private,struct 默认是 public(兼容c语言中的结构体)
4.权限区域以一个访问符开始,另一个访问符结束。
class Person
{
//private://默认的private(如果没有写访问符则person里的任何东西都拿不出去,因为private)
//.....
//里面的代码到下面的public,是private的区间
//
public:
//显示基本信息
void ShowInfo();
private:
char* _name; //姓名
char* _sex; //性别
int _age; //年龄
};
注意:访问限定符只在编译中有效,因为在编译过程中会检查是否有越界行为。当映射到内存后,这个限制就没了。类的实例(对象)通常以一个连续的内存块形式存在,所以没有限制
面试题:C++中的struct和class的区别是什么?
答案:1.struct充当了两个角色,1.结构体2.类。而class只是类的关键词。
2.struct默认的访问限定是public(兼容c语言结构体),class的是private。
类的封装
封装就是把数据和使用数据的方法放到类中。隐藏其中细节,对外开放部分接口,来操作对象。
很容易想,你是刷抖音的,你只要知道刷就行了,你不可能说在你手机上你还可以把抖音的功能改了。这也变相说明了封装就是一种管理,管理数据不被随意修改(因为有访问限定符)。
类的作用域
class Person
{
public:
//显示基本信息
void ShowInfo();
private:
char* _name; //姓名
char* _sex; //性别
int _age; //年龄
};
//这里需要指定ShowInfo是属于Person这个类域
void Person::ShowInfo()
{
cout << _name << "-" << _sex << "-" << _age << endl;
}
作用域:我们平常说的全局和局部就是作用域,全局变量,局部变量。
类就是定义了一块新的域。我们要使用其中的接口和变量时,需要用"::"来指定你这个接口或函数是哪一个域的。
类的实例化
用类类型创建对象的过程,称为类的实例化。
实例化,就如字面意义一样,你定义好了一个类那就是虚的因为只是一个设计。实例化就是让虚的变实,就是将设计造出来。很容易想:造车子设计图纸是虚的,造出来车子能跑了才是实的。
1.只有实例化后你才有内存,你虚的时候什么都没有,实的时候你的车子才是有体积的。
2.一个类可以实例化出多个对象。很容易理解,你是车子制造商,一张图纸为模版就可以造出一堆。
上图就是怎么实例化。
类对象存储
类中既有函数又有成员变量。那这样怎么算呢?
class Person
{
public:
//显示基本信息
void ShowInfo()
{
cout << _name << "-" << _sex << "-" << _age << endl;
}
public:
char* _name; //姓名
char* _sex; //性别
int _age; //年龄
};
因为我们一个类可以创建多个对象(实例化),对于不同的对象,里面的变量可能不同,但是函数是相同的(使用方法)。就像抖音,每个人的关注和喜欢不同,但是功能刷抖音看视频是相同的。
所以类实例化后,成员变量每个对象单独一份,但是函数是在公共代码区里共用的。
// 类中既有成员变量,又有成员函数 最终是4字节
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数 最终是1字节
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类 最终是1字节
class A3
{};
所以一个对象的大小就是成员变量的大小,空类和只有函数的类,只有1字节。
这是为了标识,就算这个类什么都没有,但是被实例化后就代表这个类是真实存在的,要给1字节用来占位,表示存在。
结构体内存对齐规则
- 第一个成员在与结构体变量偏移量为0的地址处。(即结构体的首地址处,即对齐到0处)
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
对齐数 = 该结构体成员变量自身的大小与编译器默认的一个对齐数的较小值。
结构体内存对齐详解请看->点点点!!!