c++基础篇(二)——类与对象入门(上)

作者介绍:

关于作者:东条希尔薇,一名喜欢编程的在校大学生
主攻方向:c++和linux
码云主页点我
本系列仓库直通车
作者CSDN主页地址

我们以前已经对c语言进行了学习,但我们都一定听过。

c语言是面向过程的语言,而c++是基于面向对象的编程语言,那么什么是面向对象,如何进行面向对象编程,这是我们这一章需要解决的问题。


目录

  • 认识面向对象
  • 类的引入
  • 类的使用和封装
    • 类的表示方式
    • 类的访问限定符与封装(重要)
  • 类的实例化
    • 定义
    • 实例化出的类占的空间大小
  • this指针

认识面向对象

那么,面向过程和面向对象到底有什么区别?

首先画两个草图

c++基础篇(二)——类与对象入门(上)_第1张图片
面向过程采用自顶向下的思想,将待解决问题分解成一个个方法(函数),通过函数方法的调用来解决这个问题

比如,我们组织到西藏的旅行,我们怎么去,带什么东西去,怎么带,我们全部把它分解成一个个步骤去完成

下面是面向过程

c++基础篇(二)——类与对象入门(上)_第2张图片
面向对象我们将待解决问题拆解成一个个的对象,对象间通过方法(函数)来进行交互,通过对象间的交互来完成我们待解决的问题

例如,假如我们在学校里面上课,面向对象思想把我们划分成一个学生对象,然后把教学内容也划分成一个个对象,通过我们这两类对象,可以完成上课这个动作

类的引入

因为我们要把一个个特征相同的对象划分在一起,所以在面向对象编程里面引入了类这一个东西

而在c++里面的类,首先是通过c的结构体来完成的

在c语言中,如果我们要定义成一个学生类型,可以这么定义

struct Stu
{
	char name[20];//姓名
	char sex[5];//性别
	int age;//年龄
};

我们在主函数中这么定义,一个学生对象就诞生了

struct Stu s1={"张三","未知",18};

当然我们可以对其进行访问

printf("%s\n",s1.name);//打印姓名

而在c++里面,struct已经升级到了具有类的特性,所以为了适应面向对象中对象间的交互,c++的struct内可以定义函数

比如我们要初始化和访问学生的信息

struct Stu
{
	void Init(const char*name,char* sex,int age)
	{
		strcpy(_name,name);
		strcpy(_sex,sex);
		_age=age;
	}
	void Print()
	{
		cout<<_name<<" "<<_sex<<" "<<_age<<endl;
	}
	//以上都是结构体成员函数
	char _name[20];//姓名
	char _sex[5];//性别
	int _age;//年龄
};

我们可以直接使用

Stu s1;//c++结构体的声明不用加struct
Stu.Init("张三","未知",18);
Stu.Print();

而上面这种结构体的定义,在c++通常使用class来代替

结构体里面定义的变量,通常叫成员变量
结构体里面定义的函数,通常叫成员方法或成员函数
结构体中的元素被称为类的成员

下面我们就来详细介绍一下class

类的使用和封装

类的表示方式

类的标准定义如下:

class className
{
 // 类体:由成员函数和成员变量组成

}; // 一定要注意后面的分号

而成员函数定义的位置,有两种方法,要么把函数定义在类内,要么把函数定义在类外,而声明在类内

我们前一节就是用的第一种方法

在第一种方法中,编译器通常会将函数当做内联函数处理

但在大型项目中,我们通常采用第二种方法,因为项目中我们要采取定义和声明分离的策略,方便管理

但是我们要在类外定义时,一定不能忘记在函数名前加作用域限制符

因为类的作用域仅在类内部,在外面定义必须加上

void Stu::print()
{
	
}

类的访问限定符与封装(重要)

在了解访问限定符前,我们首先来了解一下封装

封装是c++类的三大特性之一,它实现的功能是可以对某些成员属性实施对外隐藏封闭管理,仅实现一些对外的接口来访问类的一些属性和进行对象间的交换,被封装的成员在外不可被访问

封装证明了c++类之间管理较严格

封装本质上是一种管理:我们如何管理兵马俑呢?比如如果什么都不管,兵马俑就被随意破坏了。那么我们首先建了一座房子把兵马俑给封装起来。但是我们目的全封装起来,不让别人看。所以我们开放了售票通
,可以买票突破封装在合理的监管机制下进去参观。类也是一样,我们使用类数据和方法都封装到一下。不想给别人看到的,我们使用把成员封装起来。

如何实现封装和开放呢?c++提供了三种访问限定符

限定符名 作用
public 在类内类外可以被访问
private 只能在类内访问,类外不可被访问
protected 只能在类内访问,类外不可被访问

其中private和protected有什么区别呢?我们学了继承和友元后再进行详细讲解~

那么,有限定符后,我们可以对我们定义好的学生类型进行改造了

假如我们不想让外界看到我们的成员变量,仅提供打印和初始化两个接口

class Stu
{
public:
	void Init(const char*name,char* sex,int age)
	{
		strcpy(_name,name);
		strcpy(_sex,sex);
		_age=age;
	}
	void Print()
	{
		cout<<_name<<" "<<_sex<<" "<<_age<<endl;
	}
private:
	char _name[20];//姓名
	char _sex[5];//性别
	int _age;//年龄
};
Stu s1;
s1.Init();
s1.name;//编译报错,因为private不可在类外被访问
s1.Print();//只能通过这种方式访问类中元素

补充:

  1. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  2. class的默认访问权限为private,struct为public(因为struct要兼容C)

类的实例化

定义

我们定义的类,其实相当于是设计房子的图纸,它是不会占实际内存的

而我们把图纸变成实际的房子,让它占有一定内存的过程,叫类的实例化

实例化方式:

Stu s1;将stu类实例化

实例化出的类占的空间大小

我们在计算内存时,要首先考虑一个问题,类中的成员变量存在哪里,类里面的函数存在哪里?
我们不妨先计算一下下面这个类的大小

class A
{
public:
	void Init()
	{

	}
	void Print()
	{
		
	}
private:
	int _a;
	int _b;
	int _c;
};

int main()
{
	cout << sizeof(A) << endl;
	return 0;
}

大小如下

在这里插入图片描述
是12字节,我们算算,3个int刚好12个字节,为什么没有算函数的大小呢?

我们可以想象,一个类可能要实例化多个对象出来,它们之间的成员变量可能不一样,而每个对象之间调用的函数却是一样的,所以就没有必要在每个对象中间存储函数了,把函数专门存储在某个地方,一起用就行了

而在c++中,成员函数存在公共代码区中,存放的是对应的函数表

特别地,为了占位表示其存在,空类会占据1字节的大小

类也要对齐,对齐规则与c的结构体一模一样

this指针

假如还是学生类,我们要使用学生类的方法

Stu s1;
Stu s2;

s1.Init();
s2.Init();

在初始化的时候,既然函数都是在公共区,那么怎么知道函数在设置s1对象,而不是s2对象呢

其实,在成员函数中,隐藏了一个this变量,而this变量是决定问题的关键

this变量的本质其实是一个形参,它传入的是调用该函数对象的地址,this不用用户定义,它在编译器中会被自动定义,自动传入

函数实际的调用如下

s1.Init(Stu* this);//自动传入,不用用户写入

函数修改如下

Stu::Init()
{
	this->_a=;//代替_a=a;
}

因为this指针本质是形参,所以指针存放在栈区,而不是类中

this一般用于需要修改对象并且要返回对象本身的时候,可以返回*this.

你可能感兴趣的:(c++基础及其STL,c++,开发语言,后端)