C++奇迹之旅:我与类和对象相遇

请添加图片描述

文章目录

  • 📝面向过程和面向对象初步认识
  • 🌠 类
    • 🌉类的引入
    • 🌉类的定义
  • 🌠类的访问限定符
    • 🌠访问限定符
  • 🌠类的两种定义方式
    • 🌉封装
  • 🚩总结


📝面向过程和面向对象初步认识

C语言是一种面向过程的编程语言,主要关注于如何实现特定的任务或功能。在面向过程编程里**:程序是由一系列步骤或过程组成的,每个步骤都有明确的输入和输出**。数据和操作数据的函数是分开的,数据结构和算法是独立的。代码结构是线性的,更关于"how"而不是"what"。适合于一些简单的、线性的、需要快速实现的程序。

C++是一种面向对象的编程语言,它引入了类、对象、继承、多态等面向对象的概念。在面向对象编程里:关注于如何组织和封装数据和功能程序是由相互交互的对象组成的,每个对象都有自己的数据和方法数据和操作数据的方法是封装在类中的,形成了对象。代码结构是模块化的,更关注于"what"而不是"how"。支持继承和多态等特性,可以实现代码的重用和扩展。适合于一些复杂的、需要良好的代码组织和可维护性的程序。

我们举个例子来更透彻的理解两个过程

比如我们熟悉的PPT制作:

  1. 制作 PPT (面向过程)

面向过程的做法是: 首先确定主题,然后设计版式,接下来添加内容,最后调整格式。每个步骤都是独立的。这种方式更关注于 PPT 制作过程中需要执行的具体步骤。

  1. 幻灯片演示系统 (面向对象)

面向对象的做法:将 PPT 制作过程封装成一个 “幻灯片演示” 类,它包含了页面、文本、图像、动画等属性,以及添加内容、设计版式、调整格式等方法。在制作 PPT 时,我们可以创建不同的幻灯片对象,每个对象都有自己的特点和功能。这种方式更关注于幻灯片这个整体对象,以及它的属性和行为。

因此,比较可以得出:

  • 面向过程:关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
  • 面向对象:关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成

在此,我们可以初步了解代码里C语言怎么实现面向过程的和C++语言怎么面向对象的:

  1. 我们定义了一个 calculate_circle_area 函数,它接受圆的半径作为参数,计算并返回圆的面积,函数内部使用了 PI 宏定义常量,并使用公式计算面积,
#include <stdio.h>
#define PI 3.14159

double calculate_circle_area(double radius) 
{
    return PI * radius * radius;
}

int main() 
{
    double radius = 5.0;
    double result = calculate_circle_area(radius);
    printf("The area of the circle with radius %.2f is %.2f\n", radius, result);
    return 0;
}
  1. 我们定义了一个 Circle 类,它包含了圆的半径PI 常量作为私有属性。在构造函数 Circle(double r) 中,我们初始化了半径属性。类中还定义了一个 calculateArea 方法,用于计算圆的面积。在 main 函数中,我们创建了一个 Circle 对象,并调用它的 calculateArea 方法来获得结果。
#include <iostream>

class Circle 
{
private:
    double radius;
    const double PI = 3.14159;

public:
    Circle(double r) : radius(r) {}
    double calculateArea() 
    {
        return PI * radius * radius;
    }
};

int main() 
{
    Circle circle(5.0);
    double result = circle.calculateArea();
    std::cout << "The area of the circle with radius " << circle.radius << " is " << result << std::endl;
    return 0;
}

可以看到,C 语言的面向过程实现,是定义一个函数来计算圆的面积。而 C++ 的面向对象实现则将数据和方法封装在一个 Circle 类中,体现了面向对象的特点。

从这个例子可以看出,面向过程的实现更加直接和简单,关注于如何计算圆的面积。而面向对象的实现则将数据和方法封装在一个 Circle 类中,更加强调对象的概念和行为。

🌠 类

🌉类的引入

在 C 语言中,结构体只能包含数据成员(变量),不能包含函数。,在C++中,结构体内不仅可以定义变量,也可以定义函数。

// C 语言中的栈实现
struct Stack
{
    int data[MAX_SIZE];
    int top;
};

void push(struct Stack* s, int value) 
{
    // 实现 push 操作
}

int pop(struct Stack* s) 
{
    // 实现 pop 操作
}

C语言方式实现的栈,结构体中只能定义变量,不能包含函数。
C++升级struct升级成了类,类里面可以定义函数,struct名称就可以代表类型
C++兼容C中struct的用法

// C++ 中的栈实现
struct Stack
{
    int data[MAX_SIZE];
    int top;

    void push(int value) 
    {
        // 实现 push 操作
    }

    int pop() 
    {
        // 实现 pop 操作
    }
};

🌉类的定义

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

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略

类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者成员函数。

我们定义一个学生类:姓名,性别,年龄。

class student
{
	int name;
	int sex;
	int age;
};

在定义成员变量时,为了避免与函数参数名称混淆,通常会在成员变量前加上下划线_作为前缀。这样可以很方便地区分成员变量和函数参数。

class Date
{
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	int _year; 
	int _month;
	int _day;
};
class Date
{
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    int _year;
    int _month;
    int _day;
};

int main()
{
	Date d;
	d.Init(2024, 4, 8);

	return 0;
}


在这个例子中,我们将成员变量year、month和day分别修改为_year、_month和_day。这样在Init()函数中,就可以很清楚地区分函数参数和成员变量。

然后我们运行起来,会发现报了错:“Date::Init”: 无法访问 private 成员(在“Date”类中声明)
在这里插入图片描述
这是为什么呢?这涉及到了类的访问限定符及封装,class默认访问限定符是private,所以不能直接访问,为了能在类外直接访问,因此我们可以使用public访问限定符:

class Date
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    int _year;
    int _month;
    int _day;
};

int main()
{
	Date d;
	d.Init(2024, 4, 8);

	return 0;
}

🌠类的访问限定符

🌠访问限定符

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

C++ 中,访问限定符用于控制类成员的可访问性。主要有以下三种访问限定符:publicprotectedprivate

  1. public:被声明为 public 的成员可以被类的任何部分以及类的外部访问。
class MyClass 
{
public:
    // public 成员函数
    void publicFunction() 
    {
        std::cout << _publicMember << std::endl;
    }
    // public 成员变量
    int _publicMember = 3;
};
  1. private:被声明为 private 的成员只能被类的成员函数访问,类的外部无法访问。
class MyClass 
{
protected:
    // protected 成员函数
    void protectedFunction() 
    {
        std::cout << _protectedMember << std::endl;
    }
     // protected 成员变量
    int _protectedMember = 2;

};
  1. protected:被声明为 protected 的成员可以被类的成员函数和派生类的成员函数访问,但类的外部无法访问。
class MyClass 
{
private:
    // private 成员函数
    void privateFunction() 
    {
        std::cout << _privateMember << std::endl;
    }
    // private 成员变量
    int _privateMember = 1;
};

在这里插入图片描述
三个访问限定符结合示例:

class MyClass 
{
public:
    // public 成员函数
    void publicFunction() 
    {
        // 可以访问 public 和 protected 成员
        std::cout << _publicMember << std::endl;
        std::cout << _protectedMember << std::endl;
        // 不能访问 private 成员
        // std::cout << _privateMember << std::endl;
    }

protected:
    // protected 成员函数
    void protectedFunction() 
    {
        // 可以访问 public、protected 和 private 成员
        std::cout << _publicMember << std::endl;
        std::cout << _protectedMember << std::endl;
        std::cout << _privateMember << std::endl;
    }

private:
    // private 成员函数
    void privateFunction() 
    {
        // 可以访问 public、protected 和 private 成员
        std::cout << _publicMember << std::endl;
        std::cout << _protectedMember << std::endl;
        std::cout << _privateMember << std::endl;
    }

    // private 成员变量
    int _privateMember = 1;
    // protected 成员变量
    int _protectedMember = 2;
    // public 成员变量
    int _publicMember = 3;
};

【访问限定符说明】

  1. public修饰的成员在类外可以直接被访问
  2. protectedprivate修饰的成员在类外不能直接被访问(此处protected和>private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. 如果后面没有访问限定符,作用域就到 } 即类结束。
  5. class的默认访问权限为privatestructpublic(因为struct要兼容C)
    注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

【面试题】
问题:C++structclass的区别是什么?
解答:C++需要兼容C语言,所以C++struct可以当成结构体使用。另外C++中struct还可以用来定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是publicclass定义的类默认访问权限是private。注意:在继承和模板参数列表位置,structclass也有区别,后序给大家介绍。

🌠类的两种定义方式

  1. 声明和定义全部放在类体中,需注意:成员函数如果在中定义,编译器可能会将其当成内联函数处理。
class Rectangle 
{
public:
    Rectangle(int width, int height) : width(width), height(height) {}

    int getArea() 
    {
        return width * height;
    }

    int getPerimeter() 
    {
        return 2 * (width + height);
    }

private:
    int width;
    int height;
};

在这个例子中,Rectangle 类的构造函数和两个成员函数 getArea() 和getPerimeter() 都直接在类体中定义。

  1. 声明和定义分离:
    类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
    .h文件
class Rectangle 
{
public:
    Rectangle(int width, int height);
    int getArea();
    int getPerimeter();

private:
    int width;
    int height;
};

.cpp文件

Rectangle::Rectangle(int width, int height) : width(width), height(height) {}

int Rectangle::getArea() 
{
    return width * height;
}

int Rectangle::getPerimeter() 
{
    return 2 * (width + height);
}

这里需要特别注意一下:声明和定义分离时,成员函数名前需要加类名::,这是因为编译器如果没有指定作用域时,会在全局作用域和局部作用域找。类自己定义了一个作用域,在类体外定义类成员函数时,需要用域作用域操作符::指定哪个类域。

如果没有加指定类体域,将会出现以下报错
在这里插入图片描述
修改后指定类域即可修复:
在这里插入图片描述

🌉封装

面向对象的三大特性:封装、继承、多态
封装是面向对象编程的重要思想,它通过隐藏内部实现细节,提供标准化的接口,实现了数据的安全性和系统的可维护性,是面向对象编程的基础。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

**封装本质上是一种管理,让用户更方便使用类。**比如:对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

在这里插入图片描述

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。

在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。


🚩总结

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/527328.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python+django+flask+vue贫困地区儿童资助网站22pk7

Python 中存在众多的 Web 开发框架&#xff1a;Flask、Django、Tornado、Webpy、Web2py、Bottle、Pyramid、Zope2 等。近几年较为流行的&#xff0c;大概也就是 Flask 和 Django 了 一开始&#xff0c;本文就对系统内谈到的基本知识&#xff0c;从整体上进行了描述&#xff0c…

【鸿蒙开发】系统组件Row

Row组件 Row沿水平方向布局容器 接口&#xff1a; Row(value?:{space?: number | string }) 参数&#xff1a; 参数名 参数类型 必填 参数描述 space string | number 否 横向布局元素间距。 从API version 9开始&#xff0c;space为负数或者justifyContent设置为…

万界星空科技工时管理系统功能介绍

一、工时管理系统的功能 1、工时记录与统计 工时管理系统提供了便捷的工时记录和统计功能。员工可以通过系统记录每天的上班时间、下班时间以及休息时间&#xff0c;系统会自动计算工作时长并生成工时统计报表。这一功能不仅能够准确记录员工的工作时间&#xff0c;还能够帮助…

基于大数据的汽车信息可视化分析预测与推荐系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本项目通过集成网络爬虫技术&#xff0c;实时获取海量汽车数据&#xff1b;运用先进的ARIMA时序建模算法对数据进行深度挖掘和分析&#xff1b;结合flask web系统和echarts可视化工具&#xff0c;…

如何在Rust中操作JSON

❝ 越努力&#xff0c;越幸运 ❞ 大家好&#xff0c;我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder。 前言 我们之前在Rust 赋能前端-开发一款属于你的前端脚手架中有过在Rust项目中如何操作JSON。 由于文章篇幅的原因&#xff0c;我们就没详细介绍…

QT 使用redis ,连接并使用

一.redis安装 链接&#xff1a;https://pan.baidu.com/s/17fXKOj5M4VIypR0y5_xtHw 提取码&#xff1a;1234 1.下载得到文件夹如图 course_redis为安装包。 2.启动Redis服务 把安装包解压到某个路径下即可。 打开cmd窗口&#xff0c;切换到Redis安装路径&#xff0c;输入 r…

微服务初始及Eureka注册中心

1&#xff0c;架构演变 单体架构&#xff1a;将所有业务功能集中在一个项目中开发&#xff0c;达成一个包部署 优点&#xff1a;架构简单&#xff0c;部署成本低 缺点&#xff1a;项目耦合度高 分布式架构&#xff1a;根据业务功能对系统进行拆分&#xff0c;每个业务作为独…

Codeforces Round 938 (Div. 3) A - F 题解

A. Yogurt Sale 题意&#xff1a;要购买n个酸奶&#xff0c;有两种买法&#xff0c;一种是一次买一个&#xff0c;价格a。一种是一次买两个&#xff0c;价格b&#xff0c;问买n个酸奶的最小价格。 题解&#xff1a;很容易想到用2a和b比较&#xff0c;判断输出即可。 代码&am…

小程序开发SSL证书下载和安装

在开发小程序时&#xff0c;确保数据的安全传输至关重要&#xff0c;而实现这一目标的关键在于正确获取与安装SSL证书。以下详细介绍了从获取到安装SSL证书的完整流程&#xff0c;以助您为小程序构建可靠的加密通信环境。 一、小程序SSL证书类型选择&#xff1a; 域名验证型D…

【PyTorch][chapter 25][李宏毅深度学习][Transfer Learning-1]

前言&#xff1a; 迁移学习是一种机器学习的方法,指的是一个预训练的模型被重新用在另一个任务中。 比如已经有个模型A 实现了猫狗分类 模型B 要实现大象和老虎分类,可以利用训练好的模型A 的一些参数特征,简化当前的训练 过程. 目录&#xff1a; 简介 Model Fine-Tuning (…

【C++】类和对象①(什么是面向对象 | 类的定义 | 类的访问限定符及封装 | 类的作用域和实例化 | 类对象的存储方式 | this指针)

目录 前言 什么是面向对象&#xff1f; 类的定义 类的访问限定符及封装 访问限定符 封装 类的作用域 类的实例化 类对象的存储方式 this指针 结语 前言 最早的C版本&#xff08;C with classes&#xff09;中&#xff0c;最先加上的就是类的机制&#xff0c;它构成…

Day3-HBase重要概念

HBase 结构 HRegion 概述 在HBase中&#xff0c;会从行键方向上对表来进行切分&#xff0c;切分出来的每一个结构称之为是一个HRegion 切分之后&#xff0c;每一个HRegion会交给某一个HRegionServer来进行管理。HRegionServer是HBase的从节点&#xff0c;每一个HRegionServ…

如何使用Java和RabbitMQ实现延迟队列(方式二)?

前言 昨天写了一篇关于Java和RabbitMQ使用插件实现延迟队列功能的文章&#xff0c;今天来讲下另外一种方式&#xff0c;不需要RabbitMQ的插件。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 需要安装RabbitMQ的可以看下面这篇文章。 如何使用PHP和R…

Spring Cloud微服务入门(四)

应用容错的概念 应用错误-雪崩效应 定义&#xff1a; 服务雪崩效应是一种因“服务提供者的不可用”&#xff08;原因&#xff09;导致“服务调用者不可用”&#xff08;结果&#xff09;&#xff0c;并将不可用逐渐放大的现象。 服务雪崩的过程可以分为三个阶段&#xff1a; 服…

Excel全套213集教程

Excel全套213集教程 包含技术入门93集 图表17集 数据透视35集 公式函数68 基础入门 93节 https://www.alipan.com/s/cMxuPstkS1x 提取码: 77dd 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视…

电商社交新零售:创新引领新趋势,变革新零售思维格局-亿发

新零售O2O模式是如何颠覆传统零售商业模式&#xff1f; 传统电商出现瓶颈&#xff1a; 传统电商在发展过程中逐渐出现了瓶颈&#xff0c;主要表现在市场竞争激烈、用户获取成本上升、用户黏性下降等问题。传统电商往往只能通过价格竞争或促销活动来吸引用户&#xff0c;而这种…

SSL、TLS和HTTPS:网络安全的重要基石

随着互联网的快速发展&#xff0c;网络安全问题日益凸显。为了保护数据在传输过程中的安全&#xff0c;各种加密协议和技术应运而生。SSL&#xff08;安全套接层&#xff09;、TLS&#xff08;传输层安全&#xff09;和HTTPS&#xff08;超文本传输安全协议&#xff09;是三个最…

超级agent的端语言模型Octopus v2: On-device language model for super agent

大型语言模型&#xff08;LLMs&#xff09;在函数调用方面展现出卓越的应用潜力&#xff0c;特别是针对Android API的定制应用。与那些需要详尽描述潜在函数参数、有时甚至涉及数万个输入标记的检索增强生成&#xff08;RAG&#xff09;方法相比&#xff0c;Octopus-V2-2B在训练…

uniapp引入微信小程序版本VantUI,使用VantUI的自定义tabbar,并解决自定义tabbar出现闪烁的情况

1.uniapp引入微信小程序版本VantUI 去vant官网下载源码&#xff0c;源码放在github&#xff0c;自行去下载下来 https://vant-contrib.gitee.io/vant-weapp/#/home 在pages.json的globalStyle里面注册组件 "globalStyle": {"navigationBarTextStyle": &qu…

gitlab使用

个人笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔&#xff1a;工作总结随笔_8、以前工作中都接触过哪些类型的测试文档-CSDN博客 目录 一&#xff1a…