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

1.C语言面向的是过程,面向过程以函数为中心,程序由一系列函数调用组成。它关注解决问题的步骤(怎么做)。 2.C++面向的是对象,面向对象以对象为中心,程序由多个对象的交互组成。它关注的是对象之间的关系(谁来做)。

就比如交作业: C语言: 我把作业交给课代表->课代表拿到作业并检查->课代表把作业交给老师 C++: 我->课代表->老师

  • 对于面向过程,我们需要操纵每个对象去实现对应的工作(函数调用)
  • 对于面向对象,每个对象知道自己要做些什么,不需要我们进一步的操纵

二、类的定义

引入:在C语言里,我们的结构体里面是不能够定义函数的,而C++里的类里面却可以定义函数,我们可以将类看作是C语言结构体的plus版。定义类的关键字为 class类是类似于结构体的一种用户自定义的数据类型。

  • struct 的升级:struct 升级成了类,主要体现在C++里的 struct 里面可以定义函数了
2.1 类的定义格式

代码语言:javascript

AI代码解释

class Date//类的名字
//类的主体:由成员函数和成员变量组成
{
public:
	//成员函数
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	//成员变量
	int _year;
	int _month;
	int _day;
};
};

1.格式定义

1.定义类的关键字:class,虽然 struct 也可以定义类,但一般情况下还是推荐由 class 来定义。 2.Date为类的名字。 3.花括号里的是类的主体,简称类体。 4.类体由成员函数和成员变量组成,其中成员函数也叫做类的方法,成员变量也叫做类的属性。成员变量和成员函数都是类的成员。

2.为了区分成员变量,我们一般在定义成员变量的时候,会在变量名称之前或之后加一个特殊符号比如_。比如上面代码成员变量 year、month、day 加_是为了更好区分它们和函数的形参。这个并不强制,只是惯例。 3.定义在类里面的成员函数默认为inline

2.2 访问限定符

C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的⽤⼾使⽤。 访问限定符分为:public(共有)、protected(保护)、private(私有)

在这里插入图片描述

在这里插入图片描述

  1. 由 public 修饰的成员在类外可以直接被访问。
  2. 由 protected 和 private 修饰的成员在类外不可以被直接访问(我们目前阶段可以认为 protectd 和 private 差不多)
  3. 划分区域:从一个访问限定符开始,直到下一个访问限定符或者是遇到 ‘}’ 为止
  4. 由 class 定义的类,其成员默认被 prevate 修饰
  5. 由 struct 定义的类,其成员默认被 public 修饰
2.3 类域

类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。比如接下来要提到的第二种定义方式。

2.4 两种定义方式
2.3.1 声明与定义不分开
  1. 声明和定义全部放在类体中。这种情况下,编译器可能会将成员函数当作内联函数来处理

代码语言:javascript

AI代码解释

//.h文件
class Stack
{
public:
	 // 成员函数 
	void Init(int n)
	{
 		 arr = (int*)malloc(sizeof(int) * n);
		 if (nullptr == arr)
		 {
			 perror("malloc fail");
			 return;
		 }
		 capacity = n;
		 top = 0;
	}
private:
	 // 成员变量 
	 int* arr;
	 size_t capacity;
	 size_t top;
 };
2.3.2 声明与定义分开
  1. 类的声明放在 .h文件里,类的定义放在 .cpp文件里。
  2. 在类体外定义函数时,别忘了使用 :: 作用域操作符,并指明在哪个域里。

代码语言:javascript

AI代码解释

//.h文件
class Stack
{
public:
	 // 成员函数 
	 void Init(int n = 4);
private:
 	// 成员变量 
 	int* arr;
	 size_t capacity;
	 size_t top;
 };
 
//.cpp文件
// 声明和定义分离,需要指定类域 
void Stack::Init(int n)
{
 	arr = (int*)malloc(sizeof(int) * n);
	 if (nullptr == arr)
	 {
		 perror("malloc fail");
		 return;
	 }
	 capacity = n;
	 top = 0;
}

三、类的实例化

概念:

  1. 什么是对象?类是一种用户自定义的数据类型,可以类比利用结构体类型定义变量。而对象就是类这种数据类型定义的变量即实例。
  2. 而类的实例化就是类在物理空间下创建出对象的过程,对象就是类的具体实例。
  3. 类是抽象的,而对象是具体的。可以说,类是对对象的一种抽象化的描述。类只是限定了对象有哪些成员变量,类只是声明,它并没有为这些成员变量分配空间。只有当类实例化为对象时,才会为这些成员变量分配内存。
  4. 类可以实例化多个对象,这些对象都占有一定的物理空间。类就好比是一个建筑图纸,它是抽象的,不能住人,不能实现房子的功能。而对象就是依照这副图纸造出来的房子,能够实现房子的功能。

四、类对象模型

4.1 基本模型
  1. 类对象中只储存成员变量,不储存成员函数。
  2. 成员函数放在公共代码区,只要是这个类实例化出的对象,就都可以使用这个函数。

不储存成员函数的原因函数名的本质是指向函数代码内存地址的指针。倘若每个对象都要存储这个成员函数,相当于每个对象都要储存这个函数的指针,而函数的地址是不变的,这是一种对于空间的浪费。

4.2 类对象大小计算方法
  1. 类对象的大小就是其中成员变量所占内存之和,计算方法与结构体相同,也遵循结构体内存对齐规则。
  2. 对于没有成员变量的对象,编译器会为其分配 1 字节大小的内存,相当于占位

测试:

代码语言:javascript

AI代码解释

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
// 计算⼀下A/B/C实例化的对象是多⼤? 
class A
{
public:
	void Print()
	{
		cout << _ch << endl;
	}
private:
	char _ch;
	short _s;
};
class B
{
public:
	void Print()
	{
		//...
	}
};
class C
{};
int main()
{
	A a;
	B b;
	C c;
	cout << sizeof(a) << endl;
	cout << sizeof(b) << endl;
	cout << sizeof(c) << endl;
	return 0;
}

结果:

在这里插入图片描述

在这里插入图片描述

五、this指针

我们看下面的一段代码:

代码语言:javascript

AI代码解释

#include<iostream>
using namespace std;
class Date
{
public:
	//初始化
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//打印
	void Print()
	{
		cout << _year << '/' << _month << '/' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1, d2;
	d1.Init(2025, 5, 4);
	d2.Init(2025, 5, 5);
	d1.Print();
	d2.Print();
	return 0;
}

测试结果:

在这里插入图片描述

在这里插入图片描述

我们能够观察到: Date类中有 Init() 和 Print() 这两个成员函数,我们在对 d1 和 d2 这两个对象进行初始化和打印的时候,函数是怎么知道我们是针对的哪个呢?因为我们并没有将对象的地址传入。

-------这是因为C++里引入了一个隐含的 this 指针来解决这个问题。它不由用户主动添加,而由编译器完成添加。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐