C语言转型之路:从C到C++的类与对象初探

news2024/11/20 8:25:03

欢迎来CILMY23的博客

本篇主题为 C语言转型之路:从C到C++的类与对象初探

个人主页:CILMY23-CSDN博客

个人专栏系列: Python | C语言 | 数据结构与算法 | C++

感谢观看,支持的可以给个一键三连,点赞关注+收藏。


写在前头:

面向过程和面向对象的认识:

C语言是面向过程的,关注的是过程分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象将一件事情拆分成不同的对象,靠对象之间的交互完成。面向对象都有以下三种特性:封装、继承、多态

例如:人用洗衣机洗衣服,C语言关注的是如何洗衣服,而C++会将这件事拆分成多个对象,洗衣机,人,洗衣粉,衣服。我们关注这些对象,而不关心是如何洗衣服的。 


目录

一、类和对象

1.1 类的引入

1.2 类的访问限定符

1.3 类的定义 

1.3.1 声明和定义全在类中 

1.3.2 声明和定义分离 

1.4 类的封装 

1.5 类的作用域 


一、类和对象

在面向对象编程中,对象是类的一个实例。类是一个抽象的概念,它描述了一类对象共同的属性和行为。通过类可以创建多个具体的实例,这些实例就是对象

对象可以是现实世界中的物体(如汽车、动物等)、概念(如账户、订单等)或者抽象数据类型(如栈、队列等)。每个对象都有自己的状态(属性)和行为(方法)。状态是描述对象的特征,而行为是对象能够执行的操作。

例如,如果有一个“汽车”类,那么具体的一辆汽车(比如一辆特斯拉Model 3)就是这个类的一个对象。这辆汽车有自己的颜色、速度、品牌等属性,同时它能够进行加速、减速、转向等行为操作。

1.1 类的引入

 C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如: 之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现, 会发现struct中也可以定义函数。

例如:

typedef int DataType;
struct Stack
{
    //栈的初始化
    void Init(size_t capacity)
    {
        _array = (DataType*)malloc(sizeof(DataType) * capacity); 
        if (nullptr == _array)
        {
            perror("malloc申请空间失败"); return;
        }
        _capacity = capacity;
        _size = 0;
    }
    //插入
    void Push(const DataType& data)
    {
        // 扩容
        _array[_size] = data; 
        ++_size;
    }

    DataType Top()
    {
        return _array[_size - 1];
    }
    //栈的销毁
    void Destroy()
    {
        if (_array)
        {
            free(_array);
            _array = nullptr; _capacity = 0;
            _size = 0;
        }
    }

    DataType* _array;
    size_t _capacity;
    size_t _size;
};

 我们发现C++兼容C,在c++中同样可以运行C的玩法,同时我们把其中的变量叫做成员变量其中的函数称为成员函数。但C++更喜欢用class来定义上述的结构体,于是类的结构就确定了。

 类的结构如下:

//类的定义
class classname
{
	//类体,由类的成员变量和成员函数构成
	//…………………………
};	//注意有分号

class 是C++中类的关键字,classname为类的名字,{}为类的主体,注意和结构体一样,末尾的分号不能省略。

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

我们习惯的在成员变量前加一个横杠以用来区分形参和成员变量。

1.2 类的访问限定符

C++中类的访问限定符有三种,

  1. public 公有
  2. protected 保护
  3. private 私有 

在目前这个学习阶段我们可以认为2,3没有区别(实际有区别),我们主要讲还是1,3。 

访问限定符的特点: 

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


 在这里我们使用日期类举例 :

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

int main()
{
	Date d1;
	d1.Init(2024, 04, 17);

	//d1.year++; 无法被访问
	
	return 0;
}

 我们想让类的成员被访问就用公有,不想被访问就私有,如果我们这里把class改成struct也是可以的

1.3 类的定义 

1.3.1 声明和定义全在类中 

注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

 我们以学生类为例:

class Student
{
public:
	void StuInit(const char* name,int age,const char* sex)
	{
		strcpy(_name, name);
		_age = age;
		strcpy(_sex, sex);
	}

	void showInfo()
	{
		cout <<"名字:" << _name << "  " 
		  	 <<"年龄:" <<_age << "  "
			 <<"性别:" <<_sex << endl;
	}

private:
	char _name[20];
	char _sex[20];
	int _age;
};

int main()
{
	Student s1;
	s1.StuInit("zhangsan", 18, "male");
	s1.showInfo();

	return 0;
}

1.3.2 声明和定义分离 

假设我们要声明和定义分离,这里我们用来举例:

Stack.h:

//头文件我们放成员函数,成员变量的声明
class Stack
{
public:
	//成员函数
	void Init(int n);
	void Push(int x);

private:
	//成员变量
	int* a;
	int top;
	int capacity;
};

Stack.cpp:

#include"Stack.h"

void Init(int n = 4)
{
	a = (int*)malloc(sizeof(int) * n);
	if (a == NULL)
	{
		perror("malloc fail");
		return;
	}
	capacity = n;
	top = 0;
}

void Push(int x)
{
	//...
	a[top++] = x;
}

但是我们发现在上述情况下,编译器会报错,这是因为类也有自己的作用域,编译器会从全局域,局部域搜索,找不到就会报错了。所以我们需要去类中搜索。

 Stack.cpp

#include"Stack.h"

void Stack::Init(int n = 4)
{
	a = (int*)malloc(sizeof(int) * n);
	if (a == NULL)
	{
		perror("malloc fail");
		return;
	}
	capacity = n;
	top = 0;
}

void Stack::Push(int x)
{
	//...
	a[top++] = x;
}

 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::,一般情况下,更期望采用第二种声明和定义分离的方式。

1.4 类的封装 

面向对象的三大特性:封装、继承、多态。(是面向对象编程都有的)
C++中,在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来 和对象进行交互。
封装本质上是一种管理,让用户更方便使用类。比如:对于电脑这样一个复杂的设备,提供给用 户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日 常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如 何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计 算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以 及键盘插孔等,让用户可以与计算机进行交互即可。
在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来 隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。

C++将数据和方法都放到类中,利用访问限定符对成员进行限制,想访问的设置成公有,不想访问的设置成私有。

1.5 类的作用域 

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

如果我们需要访问类域,就需要用::来访问

例如:当我们在声明和定义分离的时候,我们就会将类前面加个作用域操作符,来表明是哪个类域的。

class Student
{
public:
	void StuInit(const char* name, int age, const char* sex);
	void showInfo();

private:
	char _name[20];
	char _sex[20];
	int _age;
};

void Student::StuInit(const char* name, int age, const char* sex)
{
	strcpy(_name, name);
	_age = age;
	strcpy(_sex, sex);
}

void Student::showInfo()
{
	cout << "名字:" << _name << "  "
		<< "年龄:" << _age << "  "
		<< "性别:" << _sex << endl;
}

int main()
{
	Student s1;
	s1.StuInit("zhangsan", 18, "male");
	s1.showInfo();

	return 0;
}

一些总结:

  • C++ 兼容C struct的用法,但是同时升级成了类,可以将函数写于类中
  • 类要定义哪些东西是不确定的,类要设计哪些东西,取决于要完成哪些东西
  • 类提供了三种访问限定符,它们分别是public(公有),private(私有),protected(保护)
  • class 的访问默认是private,而struct默认访问是public
  • 声明和定义分离的时候,成员函数的定义需要加 类名::
  • 封装的本质是一种管控

感谢各位同伴的支持,本期C++篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PAN2416AF 2.4GHz 无线收发 SOC 芯片

1 概述 PAN2416AF 芯片是工作在 2.400~2.483GHz 世界通用 ISM 频段的单片无线收发芯片。该芯片集 成射频收发机、频率发生器、晶体振荡器、调制解调器和低功耗 MCU 等功能模块&#xff0c;并且支持 一对多组网和带 ACK 的通信模式。 用户通过 MCU 的 I/O 口向芯片发出指令…

【源码】基于I.MX6ull驱动移植ds18b20的实验详解

文章目录 前言一、硬件连接二、代码移植1.驱动代码2.编译程序 三、移植到开发板参考连接 前言 提示&#xff1a;基于I.MX6ull驱动移植ds18b20的实验&#xff1a; 实验平台&#xff1a;正点原子alpha开发板V2.2 传感器&#xff1a;ds18b20模块 一、硬件连接 ds18b20的VCC&…

将windows作为网关

开启转发 reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /D 1 /f开启routing and remote access服务 这样局域网里面别的设备能通过windows进行上网 参考&#xff1a;https://www.cnblogs.com/chrishg/articles/12861053.html

Android的一些总结

先打开自定义的app显示欢迎->消失 打开桌面应用程序->在桌面应用程序中也要能一键启动打开视频播放的app 桌面应用程序广播接收者进行监听&#xff0c;然后打开服务/activity是可行的。 ########################## 日志&#xff0c;调试&#xff1a; Usb 无线 串口…

全新Linux教程-驱动大全-PCI和PCIe子系统-P1-从软件角度看PCI和PCIE

主题&#xff1a;为什么要引入PCI&#xff0c; 为什么要引入PCIE&#xff0c;PCIE和PCI的硬件接口大概如何&#xff1f;理解一下CPU地址和PCI地址空间的概念。 参考资料&#xff1a; * 《PCI Express Technology》&#xff0c;Mike Jackson, Ravi Budruk; MindShare, Inc. *…

比较转录组学方法推断基因共表达网络及其在玉米和水稻叶片转录组中的应用 TO-GCN时序分析-文献精读-8

Comparative transcriptomics method to infer gene coexpression networks and its applications to maize and rice leaf transcriptomes 比较转录组学方法推断基因共表达网络及其在玉米和水稻叶片转录组中的应用 TO-GCN时序分析&#xff0c;媲美加权基因共表达网络分析-WG…

免费证书和付费证书的区别

免费SSL证书和付费SSL证书都是用来实现HTTPS加密通信的安全工具&#xff0c;旨在为网站提供数据传输的机密性和完整性保护。尽管它们的基本功能相似&#xff0c;即通过公钥加密技术建立安全连接&#xff0c;但两者在以下几个方面存在显著区别&#xff1a; 1. 类型与验证级别 免…

项目二:学会使用python爬虫请求库(小白入门级)

上一章已经了解python爬虫的基本知识&#xff0c;这一次让我们一起来学会如何使用python请求库爬取目标网站的信息。当然这次爬虫之旅相信我能给你带来不一样的体验。 目录 一、安装requests 库 简介 安装 步骤 1.requests的基本使用3步骤 2.查看所使用编码 3.设置编码…

Spring Boot入门(16):让你的API文档更亮眼:Spring Boot与Swagger-UI完美整合!

1. 前言 在实际开发过程中&#xff0c;我们经常需要编写API文档来描述接口的调用方法、参数、返回值等信息。为了提高开发效率和维护便利性&#xff0c;Swagger-UI成为了API文档自动生成的一种流行方案。本文将介绍如何利用Spring Boot和Swagger-UI实现在线API文档。 2. 摘要…

应用编程之进程(三-通信篇)

所谓进程间通信指的是系统中两个进程之间的通信&#xff0c;不同的进程都在各自的地址空间中、相互独立、隔离&#xff0c;所以它们是处在于不同的地址空间中&#xff0c;因此相互通信比较难&#xff0c;Linux 内核提供了多种进程间通信的机制。 大部分的程序是不要考虑进程间…

unity学习(86)——细节优化

东西已经做出来了&#xff0c;现在需要的是优化&#xff0c;说得简单&#xff0c;做起来难。 1.122包的优化&#xff0c;避免重复创建&#xff01; 2.为何会出现一边动&#xff0c;一边不动的情况。重复登录后依旧是unity可以看到移动&#xff0c;但是exe那边看不到移动&#…

NAT基本配置

配置IP完成及缺省的路由如下&#xff1b; 此时R1pingISP是ping不通的&#xff0c;因为缺省是可以将数据传给R3&#xff0c;但是R3传不回去&#xff0c;知道目标IP地址但因其是私有内部IP&#xff0c;而自己的是公有IP&#xff0c;所以传不过去&#xff0c;此时就需要R2这个边界…

Linux 基于 TCP 协议的简单服务器-客户端应用

目录 一、相关函数 1、listen() 2、accept() 3、connect() 4、两种IP地址转换方式 5、TCP和UDP数据发送和接收函数对比 5、log.hpp自定义记录日志 二、udp_server.hpp单进程版本 三、tcp_server.cc 四、Telnet客户端&#xff08;代替tcp_client.cc&#xff09; 五…

TorchEEG文档_学习笔记1【代码详解】

文章目录 一、用户文档1.安装Pytorch2.安装TorchEEG3.安装与图算法的插件 二、教程1.使用TorchEEG完成深度学习工作流程2datasets模块3.transforms模块4.models模块5.trainer模块6.使用Vanilla PyTorch训练模型 一、用户文档 1.安装Pytorch TorchEEG依赖于PyTorch,根据系统、…

PTA L2-047 锦标赛

题目 解析 把每一场比赛看作满二叉树的一个节点&#xff0c;父节点递归遍历子节点的结果&#xff0c;进行试填。 代码 #include <bits/stdc.h>using i64 long long;struct Node {int win, lose; };void solve() {int k;std::cin >> k;int siz (1 << k);…

常见UI组件(二)

一、文本输入 1.1 概述 TextInput为文本输入组件&#xff0c;用于接收用户输入的文本内容 1.2 参数 Entry Component struct Index {build() {Column({space : 50}) {TextInput({placeholder:请输入用户名}).width(70%)TextInput({text:当前内容}).width(70%)}.width(100%).…

基于springboot+vue+Mysql的广场舞团管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Java | Leetcode Java题解之第38题外观数列

题目&#xff1a; 题解&#xff1a; class Solution {public String countAndSay(int n) {String[] arr {"","1","11","21","1211","111221","312211","13112221","1113213211",…

六、项目发布 -- 4. 电子书详情页API开发、电子书列表API开发

电子书详情页API的编写 同理如下app.get中路由、回调&#xff1b;回调中要连接数据库、接收前端传过来的值、到数据库中做查询&#xff0c;然后回调&#xff08;如果回调失败返回什么JSON&#xff0c;如果回调成功返回什么JSON&#xff09;&#xff1b;最后千万别忘记了关闭数…

面试:java中常见的锁

文章目录 概述并发编程三大特性java中常见的锁synchronized关键字&#xff08;隐式锁&#xff09;ReentrantLock 类ReadWriteLock 接口StampedLock 类 小结 概述 在Java中&#xff0c;锁是用于控制多个线程对共享资源的访问的一种机制。它有两个主要作用&#xff1a; 保证线程…