目录
我们在学习C语言的时候,它是面向过程的,关注的也是过程,是通过分析进而求解问题的步骤,通过函数调用来逐步解决问题。而我们现在学习的C++语言,它是在C语言的基础上改进优化而成,是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完 成。
举个栗子:当我们到了饭点点外卖时,打开外卖系统,这时有四大类:用户,商家,菜品,骑手,它们都有各自的属性和动作,菜品的属性是价格、味道、菜系,配料等;商家的属性是菜品名称、销量、风评等;用户的属性是地址、电话、性别等;骑手的属性是实时位置、姓名、电话。用户通过商家挑选菜品下单,商家接收单子后开始做菜,做好后会出单,然后骑手可以选择接单来取,骑手将饭菜送到用户手中完成任务。用户只关心自己点的饭菜有没有按时送达,不用管商家怎么做怎么出菜,商家也只负责出菜和接收用户的售后服务,骑手也不必知道用户点的什么菜,多少价格只管送达即可。整个过程就是用户,商家、菜品、骑手等对象间的交互。

C++是兼容C语言的,所以类的引入是将struct进行优化而成的,类是兼容struct的所有用法。
- //结构体
- typedef struct ListNode {
- int* arr;
- int top;
- int capacity;
- }LN;
-
-
- //初始化函数
- void ListInit(LN* lst,int capa) {
- lst->arr = (int*)malloc(sizeof(int) * capa);
- if (lst->arr == nullptr) {
- perror("malloc fail");
- return;
- }
- lst->top = 0;
- lst->capacity = 0;
- }
-
-
- //数据的插入
- void ListPushBack(LN* lst, int x) {
- assert(lst);
- if (lst->capacity == lst->top == 0) {
- //扩容
- }
- lst->arr[lst->top] = x;
- lst->top++;
- }
-
-
-
- int main() {
- LN lst1; //创建新对象
- ListInit(&lst1,4);
- ListPushBack(&lst1, 1);
- ListPushBack(&lst1, 2);
- ListPushBack(&lst1, 3);
- return 0;
- }
C语言的struct写法需要通过对象的形参去指向结构体成员变量,代码繁琐,可读性差
- struct ListNode {
-
- void ListInit(int capa) {
- arr = (int*)malloc(sizeof(int) * capa);
- if (arr == nullptr) {
- perror("malloc fail");
- return;
- }
- top= 0;
- capacity = 0;
- }
-
- void ListPushBack(int x) {
- if (capacity == top == 0) {
- //扩容
- }
- arr[top] = x;
- top++;
- }
-
- int* arr;
- int top;
- int capacity;
- };
-
- int main() {
- ListNode lst1;
- lst1.ListInit(4);
- lst1.ListPushBack(1);
- lst1.ListPushBack(2);
- lst1.ListPushBack(3);
- lst1.ListPushBack(4);
- return 0;
- }
而C++写法的struct类中,不需要引入对象去访问结构体成员变量,而是可以直接进行访问,简单方便,代码可读性强 。
class className {
// 类体:由成员函数和成员变量组成 };
// 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分 号不能省略。 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
需注意:成员函数如果在类中定义,编译器可能会将其当成内 联函数处理。
- class ListNode {
- //类成员函数在类内定义
- void ListInit(int capa) {
- }
- //类成员函数
- void ListPushBack(int x) {
- }
-
- //类成员变量
- int* arr; //指针
- int top; //现有长度
- int capacity; //可存储容量
- };
注意:成员函数名前需要加类名::
- #pragma once
- #include
- #include
- #include
- using namespace std;
-
-
- class ListNode {
- public:
- //类成员函数在类内定义
- void ListInit(int capa);
- //类成员函数
- void ListPushBack(int x);
-
- //类成员变量
- int* arr;
- int top;
- int capacity;
- };
- #include"标头.h"
-
- void ListNode::ListInit(int capa) {
- arr = (int*)malloc(sizeof(int) * capa);
- if (arr == nullptr) {
- perror("malloc fail");
- return;
- }
- top= 0;
- capacity = 0;
- }
-
- void ListNode::ListPushBack(int x) {
- if (capacity == top == 0) {
- //扩容
- }
- arr[top] = x;
- top++;
- }
我们在今后的学习中,要尽量以方式二的方式定义类,声明与定义分离可以提供清晰,整洁的程序元素视图。当我们做项目时可能会有几千行的代码,将声明与定义分离可以更好的看到成员变量与函数实现,方便阅读,而且可以避免原码的泄漏。
此外在C语言中习惯是先定义变量,再实现函数;而在C++中,编译器会把类看成一个整体,成员函数可以在上面,变量在下,也可以相反,编译器对其不会有严格的要求。
类的声明是造房的图纸,并没有实体的建筑存在,而只有创建出类对象后,才是真正存在的房子。你才能去使用房子里的物品,实际存储数据,占用物理空间。

【访问限定符说明】
1. public修饰的成员在类外可以直接被访问。
2. protected和private修饰的成员在类外不能直接被访问。
3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class的默认访问权限为private,struct为public(因为struct要兼容C)
- class ListNode {
- public:
-
- void ListInit(int capa) {
- }
-
- void ListPushBack(int x) {
- }
-
- public:
- //类成员变量
- int* arr;
- int top;
- private:
- int capacity;
- };
我们可知:类中只有capacity是私有成员,所以main函数中无法对其访问。

对于第五点来说:

从上图中代码可知:class不加访问限定修饰符时,默认都是私有成员!!!类外不能访问。

从上图中代码可知:struct类中不加访问限定修饰符时,默认都是公有成员!!!类外可以访问。
通过学习到访问限定修饰符后,我们可以总结出:C语言可以随意的访问数据,没有保护性,安全性;而C++中,增删查找数据时,只能调用公有成员去访问,这就是C++面向对象三大特性之一的——封装性。
封装:将数据和操作数据的方法有机结合,隐藏对象的属性与细节,仅对外公开接口和对象进行交互。封装本质上是一种管理,让用户更方便的使用类。
- class Date{
- public:
- Date(int year = 1999, int month = 10, int day = 5) {
- year = year;
- month = month;
- day = day;
- }
- private:
- int year;
- int month;
- int day;
- };
会出现一个问题:谁赋值给谁?是形参赋值给成员变量,还是成员变量赋值给形参?
为了区别成员变量与函数形参,要使成员变量前加 " _ "(大部分公司都是这样要求的)
private:
int _year;
int _month;
int _day;