C++基础精讲篇第4讲:类和对象的初步认识

C++基础精讲篇第1讲:输入输出流+命名空间+缺省参数_King_lm_Guard的博客-CSDN博客_c++输入输出流关键字https://blog.csdn.net/King_lm_Guard/article/details/125704894C++基础精讲篇第2讲:函数重载+引用_King_lm_Guard的博客-CSDN博客https://blog.csdn.net/King_lm_Guard/article/details/125714932C++基础精讲篇第3讲:内联函数+auto关键字_King_lm_Guard的博客-CSDN博客https://blog.csdn.net/King_lm_Guard/article/details/125836830     在C++基础篇前三讲中博主为大家详细讲解了从C语言学完跨度到C++学习之前需要掌握的重点补充概念,强烈建议读者们能够把前三讲的知识阅读了再开始C++关于类和对象的学习。

      今天这一讲正式开启了C++特有的也是非常重要的知识,即类和对象。这是我们升入学习C++的基础,希望读者们能跟着博主的步伐一起学习,能够有不错的收获,下面开始学习吧。

目录

1、面向过程和面向对象的初步认识

1.1 面向过程

1.2 面向对象

2、类的引入及相关特性

2.1 类的引入

2.2 什么是类

2.2.1 类的结构形式

2.2.2 类的定义

2.2.2 类的定义遵循的规则

3、类的访问限定符及封装

3.1 访问限定符详解

3.1.1 组成

3.1.2 特性

3.2 struct和class的访问限定符特性

3.3 封装

4、类的作用域及作用域操作符

5、类的实例化

6、类对象的大小计算

7、结语


1、面向过程和面向对象的初步认识

1.1 面向过程

       C语言是面向过程的,其重点关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

        比如,以外卖系统为例,在C语言中关注的是用户点餐、商家接单、送餐员的送餐流程,在整个过程中,C语言重点关注流程函数的实现。

1.2 面向对象

     C++是基于面向对象的,,其重点关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

    比如,同样以外卖系统为例,在C++中关注的是用户、商家、骑手这三个对象之间的关系,商家并不关注骑手是怎么送餐的。但我们需要注意:C++虽然说是面向对象的,但其实C++并不是纯面向对象的,它可以面向对象和面向对象混编。从这里我们也可以看出C++兼容C语言的语法。

2、类的引入及相关特性

2.1 类的引入

      在C语言中,我们知道,结构体struct只能用来定义变量,如下所示,可以用来定义人的基本信息,但是在C++中,结构体struct内不仅可以定义变量,也可以定义函数。

      这是为什么呢?其实C++为了引入类和对象的概念,在C++中有专门定义类的关键字:class。但为了填C语言结构体的坑,就在C++中给结构体赋予了这种可以定义变量和函数的功能。但在今后关于C++的学习中,我们将结合class来使用。

C语言结构体定义:

typedef struct st
{
	char name[20]; //名字
	int age;       //年龄
	char sex[5];   //性别
	char id[20];   //电话
}s;

C++结构定义:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>

typedef struct st
{
//定义函数1
	void print()
	{

	}
//定义函数2
	int test()
	{

	}

	char name[20]; //名字
	int age;       //年龄
	char sex[5];   //性别
	char id[20];   //电话
}s;

int main()
{
	s s1;
	s1.print();
	s1.test();
    s1= { "zhansan",18,"nan","123456789" };

	return 0;
}

2.2 什么是类

2.2.1 类的结构形式

class className
{
   // 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号

       在C++中定义类的关键字为classclassname为类的名字{}中的内容是类的主体,注意类定义结束后后面的分号不能省略。

       类体中内容称为类的成员:

1、类中的变量称为类的属性或成员变量;

2、类中的函数称为类的方法或者成员函数。

注意:类本身就是一个域。

2.2.2 类的定义

1、函数声明和定义都放在类体中。

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
using namespace std;

class Person
{
public:
	void print()
	{
		cout << name << " " << age << " " << sex << " " << id << " " << endl;
	}
public:
	const char* name; //名字
	int age;       //年龄
	const char* sex;   //性别
	const char* id;   //电话
};

int main()
{
	Person st;
	st.name = "zhansan";
	st.age = 20;
	st.sex = "nan";
	st.id = "123456";
	st.print();
	return 0;
}

注意:当成员函数声明和定义均在类中定义时,编译器可能会将其当成内联函数处理,此时被当成内联以后,调试的时候就进不去该函数类中,因为此时已经不是函数了。

       关于这里的内联的概念及用法在基础篇第三讲中详细讲解过,大家可以在本博客头部直接点击链接访问学习。

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
using namespace std;
class Add
{
public:
	void add(int a, int b)
	{
		cout << a + b << endl;
	}
public:
	int a;
	int b;
};

int main()
{

	Add s;
	s.add(10, 20);
	return 0;
}
函数声明和函数定义放在类中时自动处理成内联函数的案例

2、类声明放在.h文件中,成员函数定义放在.cpp文件中。

 注意:

①当我们将函数的声明和定义分开时,此时就不会存在被编译器当作内联的情况了,因为内联函数不支持函数定义和声明分开,这在基础篇第三讲中详细讲解过,此时通过汇编我们可以看到,利用call对add函数进行了调用,如下所示。

函数声明和函数定义分开时的案例

②当我们将函数声明和定义分开时,我们在函数定义中,需要在函数名前加上类名称,如:

"函数返回类型 classname::函数名()"

2.2.2 类的定义遵循的规则

1、如果是小函数想成为内联,直接将函数的声明和定义放在类中进行定义即可;

2、如果是大函数,应该声明和定义分明,此时不能使用内联。

3、类的访问限定符及封装

        C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。(访问限定符只限定域外面的访问,不限制在类内部之间的访问)。

3.1 访问限定符详解

3.1.1 组成

访问限定符public:公有
protected:保护
private:私有

3.1.2 特性

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

2、protected和private修饰的成员在类外不能直接被访问,只能被类中的其他变量或成员访问。目前而言,二者并无区别,只有在后面讲解到继承才有所区分。

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

4、如果后面没有访问限定符,作用域就到 ”}“ 即类结束;

3.2 struct和class的访问限定符特性

       struct的访问限定符为public,也就是公开的,如我们在第2讲中分析所用的案例代码所示(之所以是公开的,最主要的原因就是为了兼容C语言);

        而C++中自定义的关键字class的默认访问权限为private,也就是说,如果我们不进行说明,则编译系统会默认识别为私有。

3.3 封装

C++中面向对象有三大特性:封装、继承、多态。(面试常考)

在类和对象的学习阶段,我们主要学习封装这一概念,那什么是封装呢?


封装:将数据和操作数据的方法进行有机结合,隐藏对象(成员变量,利用private和protected)的属性和实现细节,仅对外公开接口(开放成员函数,利用public)来和对象进行交互。封装本质上是一种管理,让用户更方便使用类。


C语言中:没办法封装,规范使用函数访问数据,可以直接访问数据,但不是很规范。

C++中:可以实现封装,必须使用函数来访问数据,不能直接访问数据,严格性好,不容易出错。

4、类的作用域及作用域操作符

       类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用"::"作用域操作符指明成员属于哪一个类域。该用法在2.2.1讲中已经提到,这里不在举例说明。


       补充知识:作用域影响的是编译的时候能否找到,即作用域跟编译器的搜索规则有关系。生命周期是考虑变量在哪个区,比如在栈区,出了栈就销毁了。即生命周期和存储位置有关。 

5、类的实例化

用类这种类型创建对象的过程,称之为类的实例化。

注意:1、定义出一个类并没有分配实际的内存空间;

           2、一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,用以存储

                类中成员变量。

           3、实例化出的对象才能实际存储数据,占用物理空间。


这里涉及到声明和定义的区别,也就是开空间和没有开空间的区别,下面将重点解释:

1、开空间的就是定义;没有开空间的就是声明;

2、比如:全局变量就是定义(如果全局变量加了extern 就是声明了),而在类内的函数声明就是声明,类中定义的变量也是声明;只有当利用该类创建一个变量的时候才会开辟空间,这里的用法和c语言中的struct用法理解一样,都是利用该类或者该结构体定义一个对象或者结构体时开辟空间。此时利用类定义对象的的过程叫做类的实例化。

6、类对象的大小计算

      类的对象和C语言中的结构体一样同样符合内存对齐规则。但对于类的大小计算,需要注意:空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象

补充:结构体内存对齐规则

1、第一个成员在与结构体偏移量为0的地址处。
2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
     注意:对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
      VS中默认的对齐数为8。
3、结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

举例说明:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
using namespace std;
// 类中既有成员变量,又有成员函数
class A1 {
public:
	void f1() {}
private:
	int _a;
};
// 类中仅有成员函数
class A2 {
public:
	void f2() {}
};
// 类中什么都没有---空类
class A3
{};

int main()
{
	cout << sizeof(A1) << endl;
	cout << sizeof(A2) << endl;
	cout << sizeof(A3) << endl;
	return 0;
}

结果:A1大小:8字节;A2大小:1字节;A3大小:1字节。

7、结语

        这一讲作为C++类和对象的第1讲,基础概念比较多,需要读者们掌握的知识点也比较多,希望大家在阅读本文后,能有所收获,欢迎大家点赞、关注、支持!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值