【C++修炼之路】C++类与对象:面向对象编程的第一步

server/2025/2/27 16:41:59/

Alt

🏝️专栏: 【C++修炼之路】
🌅主页: f狐o狸x

“于高山之巅,方见大河奔涌;于群峰之上,更觉长风浩荡” 


目录

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

 二、类的定义

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

        3.1 访问限定符

        3.2 封装

1. 封装的基本概念

2. 封装的核心点

(1)数据隐藏

(2)数据校验

(3)接口暴露

 四、类对象模型

4.1 类对象大小的基本规则

4.2  结构体内存对齐规则

规则 1:成员变量的对齐值

规则 2:结构体的起始地址

规则 3:成员变量的偏移量

规则 4:结构体的总大小

五、this指针

        5.1 this指针的引出

        5.2 this指针的特性


        你是否曾经听说过“面向对象编程”(OOP)这个词,但却不知道它具体是什么意思?或者你已经对C++有了一些基础,但面对“类”和“对象”时感到困惑?不用担心,这篇文章将带你从零开始,轻松理解C++中的类与对象,掌握面向对象编程的核心概念。

        C++作为一门强大的编程语言,其面向对象特性使得代码更加模块化、可重用和易于维护。而“类”和“对象”正是面向对象编程的基石。通过本文,你将学习到:

- 什么是类?什么是对象?
- 如何定义和使用类?
- 类的访问限定符及封装
- 类成员函数的this指针

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

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

        比如你需要点一份外卖,就是打开手机软件,选择食物,下单,等待配送,取餐

        面向过程的特点是:

  • 代码以“步骤”为中心,通过函数调用来完成任务。

  • 数据和函数是分离的,没有封装的概念。

  • 如果需求变化(例如增加新的角色或功能),代码需要大量修改

         C++是面向对象的,我们会将问题中的实体抽象为“对象”,每个对象有自己的属性和行为。

 

         面向对象的特点是:

  • 将问题中的实体(用户、商家、骑手)抽象为“类”,每个类有自己的属性和方法。

  • 数据和操作数据的方法封装在一起,代码更易于维护和扩展。

  • 如果需求变化(例如增加新的角色或功能),可以通过添加新的类或方法来实现,而不需要修改现有代码。

 二、类的定义

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

        class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略
        类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数

        类的两种定义方式:

1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

class Preson
{
public:void show_Info(){cout << _name << "-" << _age << "-" << _sex << endl;}
public:char* _name;int _age;char* _sex;
};

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

	void Person::show_Info(){cout << _name << "-" << _age << "-" << _sex << endl;}

         一般为了命名好区分,我们把类里面的变量加一个前缀作为区分(如:_name)

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

        3.1 访问限定符

        C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用

【访问限定符说明】
1. public修饰的成员在类外可以直接被访问
2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class的默认访问权限为private,struct为public(因为struct要兼容C)

        3.2 封装

        面向对象的三大特性:封装、继承、多态,在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?

1. 封装的基本概念

封装的核心包括两个方面:

  1. 将数据和方法捆绑在一起:类的成员变量(数据)和成员函数(方法)被封装在一个类中。

  2. 访问控制:通过访问修饰符(如privatepublicprotected)来控制外部代码对类成员的访问权限。

就像我们的电脑,内部电路,芯片设计都是别封装起来的,只有一些外部接口(USB、充电口)留在外面

2. 封装的核心点

(1)数据隐藏
  • 将成员变量(如orderIdfoodprice)设置为private,外部代码无法直接访问或修改。

  • 只能通过公共方法(如setPricegetPrice)来间接访问或修改数据。

(2)数据校验
  • 在公共方法中添加逻辑,确保数据的合法性。例如,setPrice方法会检查价格是否为负数。

(3)接口暴露
  • 只暴露必要的公共方法(如displayOrdersetPricegetPrice),隐藏内部实现细节。

 四、类对象模型

4.1 类对象大小的基本规则

类对象的大小主要由以下因素决定:

  1. 成员变量的大小

    • 每个成员变量都会占用一定的内存空间。

    • 成员变量的类型决定了它的大小(例如,int通常占4字节,double占8字节)。

  2. 内存对齐(Alignment)

    • 为了提高内存访问效率,编译器会对数据进行对齐。

    • 对齐规则因编译器和平台而异,但通常是按照成员变量中最大类型的对齐值来对齐。

  3. 虚函数(如果存在)

    • 如果类中有虚函数,编译器会为该类添加一个虚表指针(vptr),通常占用4或8字节(取决于系统架构)。

  4. 空类的大小

    • 如果一个类没有成员变量,它的大小通常为1字节(用于占位,确保每个对象有唯一的地址。)

4.2  结构体内存对齐规则

        这里我们在复习一下结构体内存的对齐规则:

规则 1:成员变量的对齐值
  • 每个成员变量的对齐值是其自身大小和编译器默认对齐值中的较小值。

    • 例如,int的对齐值是4,double的对齐值是8。

规则 2:结构体的起始地址
  • 结构体的起始地址必须是其最大成员变量对齐值的整数倍。

规则 3:成员变量的偏移量
  • 每个成员变量的偏移量(即其在结构体中的位置)必须是其对齐值的整数倍。

    • 如果前一个成员变量的大小不满足当前成员变量的对齐要求,编译器会插入填充字节。

规则 4:结构体的总大小
  • 结构体的总大小必须是其最大成员变量对齐值的整数倍。

    • 如果最后一个成员变量的大小不满足对齐要求,编译器会在结构体末尾插入填充字节。

五、this指针

        在C++中,this指针是一个隐含的指针,它指向当前对象的地址。每个非静态成员函数(包括构造函数和析构函数)都可以通过this指针访问调用该函数的对象。this指针是C++实现面向对象编程的重要机制之一

        5.1 this指针的引出

         让我们来看下面的代码出了什么问题:

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(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}

        对于上述类,有这样的一个问题:

        Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

        C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

        5.2 this指针的特性

  1. 隐含指针

    每个非静态成员函数都有一个隐含的this指针,指向调用该函数的对象。
  2. 类型

    this指针的类型是ClassName*(指向当前类类型的指针)。在const成员函数中,this指针的类型是const ClassName*
  3. 不可修改

    this指针本身是常量指针,不能被修改(即不能指向其他对象)。
  4. 用于访问成员

    用于区分成员变量和局部变量,或返回当前对象。
  5. 静态成员函数无this指针

    静态成员函数没有this指针,因为它们不依赖于对象。
  6. 链式调用

    通过返回*this,支持链式调用(如obj.func1().func2())。

        通过本文的学习,我们已经初步了解了C++中的类与对象,包括类的定义、对象的创建、封装的概念以及this指针的作用。类是面向对象编程的基石,而对象则是类的具体实例。掌握这些基础知识,是进一步学习C++面向对象编程的关键。

        然而,类的功能远不止于此。在C++中,类有6个默认成员函数,它们由编译器自动生成,但在某些情况下需要我们手动实现。这些默认成员函数包括:

构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符

        这些函数在对象的生命周期中起着至关重要的作用,理解它们的行为和用法,将帮助我们编写更高效、更安全的代码。在下一篇文章中,我们将深入探讨这6个默认成员函数,揭开它们的神秘面纱。敬请期待!

都看到这里啦,点个小赞不过分吧~


http://www.ppmy.cn/server/171083.html

相关文章

如何进行OceanBase 运维工具的部署和表性能优化

本文来自OceanBase 用户的实践分享 随着OceanBase数据库应用的日益深入&#xff0c;数据量不断攀升&#xff0c;单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此&#xff0c;部署专门的运维工具、实施针对性的表性能优化策略&#xff0c;以及加强指标监测工作&…

1、进程和线程之间有什么区别 【高频】

进程 是 调度 和 资源分配 的最小单位&#xff0c;线程 是 执行程序 的最小单位。一个进程可以运行多个线程。 进程与线程的区别 共享信息&#xff1a; 进程间之间共享信息不方便&#xff0c;通信比较麻烦&#xff0c;需要一些特殊机制&#xff0c;如管道、有名管道、共享内存…

android studio gradle 阿里镜像

阿里云gradle镜像地址&#xff1a;macports-distfiles-gradle安装包下载_开源镜像站-阿里云macports-distfiles-gradle安装包是阿里云官方提供的开源镜像免费下载服务&#xff0c;每天下载量过亿&#xff0c;阿里巴巴开源镜像站为包含macports-distfiles-gradle安装包的几百个操…

MacOS 终端选型

MacOS终端工具选型与技术栈建议 一、核心工具对比矩阵 工具名称最新版本核心优势适用场景推荐指数引用来源iTerm25.3分屏/自动补全/多语言支持/全局搜索全栈开发/服务器运维⭐⭐⭐⭐⭐19Warp1.4AI智能补全/块编辑/现代UI/跨平台协作新手友好/团队协作⭐⭐⭐⭐39Tabby2.0多协议…

PyCharm Professional 2025 安装配置全流程指南(Windows平台)

一、软件定位与核心功能 PyCharm 2025 是 JetBrains 推出的智能 Python IDE&#xff0c;新增深度学习框架自动补全、实时性能热力图等功能1。相较于社区版&#xff0c;专业版支持&#xff1a; Web开发&#xff08;Django/Flask&#xff09;数据库工具&#xff08;PostgreSQL/…

Git原理+使用(超详细)

Git初识 当我们写项目代码时&#xff0c;需要不断的更新版本&#xff0c;那么就需要一个东西去管理这些不同版本的文件—版本控制器。 目前最主流的版本控制器就是Git。它是一个可以记录工程的每一次改动和版本迭代的管理系统&#xff0c;同时方便多人协同作业。 &#xff0…

【SpringMVC】十分钟跑起来一个SpringMVC项目

目录标题 1 项目概述1.项目结构解析2. MVC项目的结构和每个组件的作用&#xff1a;3. 项目的工作流程&#xff1a;4 后期可以扩展的点&#xff1a;2.源码学习1. HelloController 类&#xff0c;Spring MVC控制器2 springmvc-servlet.xml - Spring MVC的主要配置文件3.web 目录 …

【深度学习神经网络学习笔记(一)】深度学习介绍

深度学习介绍 深度学习介绍前言1、深度学习和机器学习的区别1.1 特征提取方面1.2 深度学习应用场景1.3 深度学习代表算法-神经网络 2、神经网络的结构组成3、深度学习的效果特点 深度学习介绍 前言 深度学习作为机器学习的一个前沿领域&#xff0c;正推动着从图像识别到自然语…