C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入

  • 前言
  • 一、面向过程和面向对象初步认识
    • C语言
    • C++
  • 二、类的引入
    • C++的类名代表什么
      • 示例
    • C++与C语言的struct的比较
      • 成员函数
      • 访问权限
      • 继承
      • 默认构造函数
      • 默认成员初始化
      • 结构体大小
    • 总结


前言

面向过程注重任务的流程和控制,适合简单任务和流程固定的场景;而面向对象则将数据和功能封装成对象,通过对象间的交互实现复杂功能,更适用于大型、复杂的软件系统开发。

类的引入是面向对象编程中的一个核心概念。通过类,我们可以创建具有相同属性和行为的对象,从而实现代码的重用和模块化。类定义了对象的结构和行为,包括对象的属性(数据成员)和方法(成员函数)。通过实例化类,我们可以创建对象,并赋予它们特定的属性值。这样,每个对象都具有独特的身份,但仍然共享类的定义和行为。类的引入使得代码更加组织化、可维护性和可扩展性,提高了软件开发效率和质量。


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

当我们开始接触编程时,首先遇到的两个核心概念便是面向过程(Procedural Programming)和面向对象(Object-Oriented Programming,简称OOP)。这两种编程范式各有其特点,并且在不同的应用场景中发挥着各自的优势。

面向过程编程,顾名思义,是以一系列按照特定顺序执行的过程或函数为核心来构建程序的。在这种编程范式中,程序员会定义一系列函数,每个函数负责完成特定的任务,然后通过一个主程序来调用这些函数,以实现特定的功能。面向过程编程的优点在于其直观性和简单性,特别适用于小规模、逻辑清晰的程序。然而,随着程序规模的扩大和复杂度的提升,面向过程编程的缺点也逐渐暴露出来,如代码重复、难以维护、可扩展性差等。

与面向过程编程不同,面向对象编程将现实世界中的事物抽象为对象,每个对象都拥有属性和方法。对象之间可以通过消息传递进行交互,从而实现复杂的功能。面向对象编程的核心概念包括类(Class)、对象(Object)、继承(Inheritance)、封装(Encapsulation)和多态(Polymorphism)。通过这些概念,面向对象编程能够更好地模拟现实世界,提高代码的可重用性、可维护性和可扩展性。

在实际应用中,面向过程和面向对象编程往往不是孤立的,而是相互补充的。对于某些特定的任务或模块,使用面向过程编程可能更加合适;而对于整个系统或大型项目,采用面向对象编程则能够更好地组织和管理代码。因此,作为程序员,我们需要根据具体的需求和场景来选择合适的编程范式,以达到最佳的开发效果。

C语言

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
在这里插入图片描述

在这里插入图片描述

C++

C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

在这里插入图片描述
在这里插入图片描述

二、类的引入

类的引入在编程中是一个核心概念,它允许我们创建具有相似属性和行为的对象集合。通过定义类,我们可以封装数据(属性)和功能(方法),从而创建出具有特定特性和行为的对象。这种封装不仅提高了代码的可读性和可维护性,还增强了代码的重用性。

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

总结:c++兼容C语言中的struct用法,但是c++将struct升级成了类

C++的类名代表什么

在C++中,类名代表了一种自定义的数据类型。类是一种用户定义的数据类型,可以封装数据和成员函数,以实现特定的功能。

类定义了一组数据成员和成员函数,用于描述对象的状态和行为。数据成员表示对象的属性和状态,而成员函数用于定义对象的行为和操作。

通过创建类的对象,我们可以实例化该类并使用类的成员函数来操作对象的数据。类提供了一种封装数据和功能的机制,使得代码可以更加模块化和可维护。

类名在C++中是用来标识该类的唯一标识符。通常按照一定的命名规范(如驼峰命名法)命名类名,以便于代码的可读性和可理解性。类名是用来声明类变量、创建对象和调用类的成员函数的重要标识符。

示例

在C语言中我们定义一个链表是按照下面的方式来定义的

typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;

在C++中定义一个链表却是按照下面这个方式来定义

 struct SListNode
{SLTDataType data;SListNode* next;
};

C++中的struct具有与类相同的能力,可以封装数据和成员函数。

C++与C语言的struct的比较

C++与C语言中的struct在定义和使用上有一些区别。

成员函数

C++的struct可以包含成员函数,而C语言的struct只能包含成员变量。

以下是一个使用C++中的struct定义一个包含成员函数的示例:

#include <iostream>struct Person {//成员变量std::string name;int age;//成员函数void display() {std::cout << "Name: " << name << ", Age: " << age <<std::endl;}
};int main() {Person p1;p1.name = "John";p1.age = 25;p1.display();return 0;
}

上述示例中,我们定义了一个名为Personstruct,它包含了两个成员变量nameage,还有一个成员函数display()。在main函数中,我们创建了一个Person对象p1,并为其成员变量赋值,然后通过调用p1.display()函数来显示该对象的信息。

而在C语言中,如下

struct Person {int age;
};
void display() {……};

上述示例中,我们可见C语言的结构体只能定义成员变量

访问权限

C++中的struct成员默认为public,而C语言中的struct成员默认为public。这是因为C++要兼容C,所以都是public,关于public可以看我的下一篇文章。

在C++中,structclass的主要区别在于默认访问权限。下面是一个示例,展示了C++中的struct成员默认为public,而C语言中的struct成员默认为public的区别:

#include <iostream>// C++中的struct,默认成员为public
struct Person {std::string name;int age;void display() {std::cout << "Name: " << name << ", Age: " << age << std::endl;}
};int main() {Person p1;p1.name = "John";p1.age = 25;p1.display();return 0;
}

在上述示例中,我们定义了一个名为Personstruct,它包含了一个string类型的name和一个int类型的age。还有一个名为display的成员函数,用于显示该结构体的信息。

我们可以直接访问struct的成员变量和成员函数,无需使用任何访问修饰符。在main函数中,我们创建了一个Person类型的结构体变量p1,并为其成员变量赋值。然后,在display函数中,我们通过p1对象直接调用成员函数来显示该结构体的信息。

需要注意的是,C语言中的struct不支持成员函数,默认情况下,所有成员都是公开的,可以直接访问。而C++中的struct可以使用成员函数,而且默认情况下成员是公开的。这是C语言和C++中struct的一个主要区别。

继承

C++的struct可以通过继承来拓展,而C语言的struct不能进行继承。关于继承可以看我的后续文章。

在C++中,可以通过继承来拓展struct,如下所示:

struct Animal {int age;
};struct Cat : public Animal {std::string name;
};int main() {Cat cat;cat.age = 3;cat.name = "Tom";return 0;
}

在上面的例子中,Cat结构体从Animal结构体继承,继承后的Cat结构体包含了Animal的成员变量age,并新增了一个成员变量name

而在C语言中,struct无法进行继承。C语言的结构体只能包含成员变量,不能继承其他结构体的成员变量或方法。下面是一个C语言中使用结构体的例子:

typedef struct {int age;
} Animal;typedef struct {Animal animal;char name[20];
} Cat;int main() {Cat cat;cat.animal.age = 3;strcpy(cat.name, "Tom");return 0;
}

在上面的例子中,Cat结构体包含了Animal结构体的成员变量age,并新增了一个成员变量name。但是这种方式并不是继承,而是嵌套了一个Animal结构体,通过嵌套来实现在Cat中包含Animal的成员变量。

默认构造函数

C++的struct可以有默认构造函数,而C语言的struct没有默认构造函数。

下面是一个具有默认构造函数的C++ struct的例子:

#include <iostream>struct Person {std::string name;int age;// 默认构造函数Person() {name = "Unknown";age = 0;}
};int main() {Person person; // 调用默认构造函数std::cout << "Name: " << person.name << std::endl;std::cout << "Age: " << person.age << std::endl;return 0;
}

在上述例子中,定义了一个Person结构体,并为其提供了默认构造函数。在默认构造函数中,将name初始化为"Unknown",将age初始化为0。在主函数中,创建了一个Person对象person,由于没有提供任何参数,因此使用了默认构造函数进行初始化。输出结果如下:

Name: Unknown
Age: 0

而在C语言中,struct没有默认构造函数的概念。在C语言中,需要手动为struct的成员变量赋初始值。下面是一个使用C语言的struct的例子:

#include <stdio.h>struct Person {char name[20];int age;
};int main() {struct Person person = {"Unknown", 0}; // 手动赋初始值printf("Name: %s\n", person.name);printf("Age: %d\n", person.age);return 0;
}

在上述例子中,定义了一个Person结构体,并在主函数中手动为其成员变量赋初始值。通过使用大括号括起来的值列表来初始化结构体对象。输出结果与前面的例子相同:

Name: Unknown
Age: 0

默认成员初始化

C++的struct可以在声明时为成员变量提供默认值,而C语言的struct不支持默认成员初始化。

下面是一个C++ struct中支持默认成员初始化的例子:

#include <iostream>struct Rectangle {int width = 0;  // 默认初始化为0int height = 0; // 默认初始化为0
};int main() {Rectangle rectangle; // 使用默认初始化值std::cout << "Width: " << rectangle.width << std::endl;std::cout << "Height: " << rectangle.height << std::endl;return 0;
}

在上述例子中,定义了一个Rectangle结构体,并在成员变量的声明时为其提供了默认值。在主函数中,创建了一个Rectangle对象rectangle,由于没有提供任何初始化值,因此会使用成员变量的默认值进行初始化。输出结果如下:

Width: 0
Height: 0

而在C语言中,不支持这种在声明时为成员变量提供默认值的特性。在C语言中,需要在初始化结构体对象时手动为其成员变量赋值。下面是一个使用C语言的struct的例子:

#include <stdio.h>struct Rectangle {int width;int height;
};int main() {struct Rectangle rectangle = {0, 0}; // 手动赋初始值printf("Width: %d\n", rectangle.width);printf("Height: %d\n", rectangle.height);return 0;
}

在上述例子中,定义了一个Rectangle结构体,并在主函数中手动为其成员变量赋初值。通过使用大括号括起来的值列表来初始化结构体对象。输出结果与前面的例子相同:

Width: 0
Height: 0

结构体大小

C语言中的struct的大小仅受成员变量的大小和对齐方式影响,而C++中的struct除了受成员变量的大小和对齐方式影响,还有可能受到虚函数表的影响。关于虚函数可以看我后续文章。

下面是一个展示C语言和C++中struct大小差异的例子:

在C语言中,struct的大小仅受成员变量的大小和对齐方式的影响,不会受到其他因素的影响。考虑以下示例:

#include <stdio.h>struct Rectangle {int width;int height;
};int main() {struct Rectangle rectangle;printf("Size of Rectangle: %zu bytes\n", sizeof(rectangle));return 0;
}

在上述C语言示例中,定义了一个Rectangle结构体,包含两个int类型的成员变量widthheight。在主函数中,使用sizeof运算符来获取结构体Rectangle的大小并打印输出。

输出结果为:

Size of Rectangle: 8 bytes

在这个例子中,widthheight各占4个字节,所以Rectangle结构体的大小为8字节。

而在C++中,struct除了受成员变量的大小和对齐方式的影响,还有可能受到虚函数表的影响。考虑以下示例:

#include <iostream>struct Shape {virtual void draw() {std::cout << "Drawing a shape." << std::endl;}
};struct Rectangle : public Shape {int width;int height;
};int main() {Rectangle rectangle;std::cout << "Size of Rectangle: " << sizeof(rectangle) << " bytes" << std::endl;return 0;
}

在上述C++示例中,定义了一个Shape结构体,其中包含一个虚函数draw()。然后定义了一个Rectangle结构体,通过公共继承从Shape继承,并添加了两个int类型的成员变量widthheight

在主函数中,创建了一个Rectangle对象并使用sizeof运算符获取其大小并打印输出。

输出结果为:

Size of Rectangle: 16 bytes

在这个例子中,除了widthheight各占4个字节,还会有额外的字节用于存储虚函数表指针,以便支持多态性。因此,Rectangle结构体的大小为16字节。

这个例子展示了C++中的struct可能受到虚函数表的影响,使得其大小与仅受成员变量大小和对齐方式影响的C语言struct不同。

总结

需要注意的是,尽管C++的struct比C语言的struct功能更强大,但C++中的class更常用于定义对象。C++中的classstruct的唯一区别在于默认访问权限,class中成员默认为private,而struct中成员默认为public


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电商技术揭秘八:搜索引擎中的SEO内部链接建设与外部推广策略

文章目录 引言一、 内部链接结构优化1.1 清晰的导航链接1. 简洁明了的菜单项2. 逻辑性的布局3. 避免深层次的目录结构4. 使用文本链接5. 突出当前位置6. 移动设备兼容性 1.2 面包屑导航1. 显示当前页面位置2. 可点击的链接3. 简洁性4. 适当的分隔符5. 响应式设计6. 避免重复主页…

c# wpf XmlDataProvider 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window12"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend…

Debian12 使用 nginx 与 php8.2 使用 Nextcloud

最近将小服务器升级了下系统&#xff0c;使用了 debian12 的版本&#xff0c;正好试试 nginx 和 php-fpm 这种方式运行 Nextcloud 这个私有云的配置。 一、基本系统及应用安装 系统&#xff1a;debian12 x86_64 位版本最小安装&#xff0c;安装后可根据自己需求安装一些工具&…

《图解Vue3.0》- 调试

如何对vue3项目进行调试 调试是开发过程中必备的一项技能&#xff0c;掌握了这项技能&#xff0c;可以很好的定义bug所在。一般在开发vue3项目时&#xff0c;有三种方式。 代码中添加debugger;使用浏览器调试&#xff1a;sourcemap需启用vs code 调试&#xff1a;先开启node服…

python标准数据类型--集合常用方法

在Python中&#xff0c;集合&#xff08;Set&#xff09;是一种无序且不重复的数据结构&#xff0c;它是由一个无序的、不重复的元素组成的。Python中的集合与数学中的集合概念相似&#xff0c;并且支持一系列常用的方法。本篇博客将深入介绍Python集合的常用方法&#xff0c;帮…

《QT实用小工具·十五》多种样式的开关控件

1、概述 源码放在文章末尾 目前实现了三种样式的开关控件按钮&#xff0c;如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef IMAGESWITCH_H #define IMAGESWITCH_H/*** 图片开关控件 * 1. 自带三种开关按钮样式。* 2. 可自定义开关图片。*/#include <QWid…

小米汽车su7全色系展示源码

源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 安装教程 纯HTML&#xff0c;直接将压缩包上传网站目录解压即可 首页截图 源码下载 小米汽车su7全色系展示源码-小8源码屋源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 …

(二)小案例银行家应用程序-创建DOM元素

● 上图的数据很明显是从我们账户数组中拿到了&#xff0c;我们刚刚学习了forEach&#xff0c;所以我们使用forEach来创建我们的DOM元素&#xff1b; const displayMovements function (movements) {movements.forEach((mov, i) > {const type mov > 0 ? deposit : w…

如何在 Ubuntu 上安装和配置 Tomcat 服务器?

简介&#xff1a;最近有粉丝朋友在问如何在 Ubuntu 上安装和配置 Tomcat 服务器&#xff1f;今天特地写这篇文章进行解答&#xff0c;希望能够帮助到大家。 文章目录 Ubuntu上安装和配置Tomcat的详细步骤Tomcat在Linux环境下的安装与配置一、下载并上传Tomcat压缩包二、启动To…

Flutter开发进阶之错误信息

Flutter开发进阶之错误信息 在Flutter开发中错误信息通常是由Exception和Error表示&#xff0c;Error表示严重且不可恢复的错误&#xff0c;一般会导致程序直接终止&#xff0c;而Exception可以被显式抛出&#xff0c;一般为代码逻辑错误&#xff0c;根据Flutter的解释说Excep…

无监督学习简介

无监督学习简介 一、定义和核心概念 无监督学习的定义 无监督学习是机器学习的一个关键分支&#xff0c;它涉及到从未标注数据中学习和提取信息。不同于其他学习类型&#xff0c;无监督学习的数据集没有提供任何显式的输出标签或结果。因此&#xff0c;这种学习方法的主要任务…

最优乘车

题目描述 H 城是一个旅游胜地&#xff0c;每年都有成千上万的人前来观光。为方便游客&#xff0c;巴士公司在各个旅游景点及宾馆&#xff0c;饭店等地都设置了巴士站并开通了一些单程巴上线路。每条单程巴士线路从某个巴士站出发&#xff0c;依次途经若干个巴士站&#xff0c;…

力扣---分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&a…

SSL VPN

1、SSL (Secure Sockets Layer)一种加密的通讯协定,用在使用者与网服器之间 【1】安全套接层 位于传输层和应用层之间,保护应用层的数据(HTTPS(443)=HTTP+TLS) 【2】版本 SSLv2 SSLv3 修改→TLS (Transport Layer Security)安全传输层协议,) 【3】模式 采用…

机器学习笔记 - 文字转语音技术路线简述以及相关工具不完全清单

一、TTS技术简述 今天的文本到语音转换技术(TTS)的目标已经不仅仅是让机器说话,而是让它们听起来像不同年龄和性别的人类。通常,TTS 系统合成器的质量是从不同方面进行评估的,包括合成语音的清晰度、自然度和偏好,以及人类感知因素,例如可理解性。 1、技术路线 (1)基…

linux 安装 pptp 协议

注意&#xff1a;目前iOS已不支持该协议 yum -y install ppp wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/pptpd-1.4.0-2.el7.x86_64.rpm yum -y install pptpd-1.4.0-2.el7.x86_64.rpm vi /etc/pptpd.conf 去除 localip 和 remoteip的注释 …

基于沙漏 Tokenizer 的高效三维人体姿态估计框架HoT

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;基于沙漏 Tokenizer 的高效三维人体姿态估计框架HoT1、研究背景2、提出方法3、模块详细3.1、什么是HoT3.2、HoT 框架3.3、Token 剪…

面试经典-Spring篇

1、解释Spring框架中bean的生命周期 实例化 通过反射去推断构造函数进行实例化 实例工厂、静态工厂 属性赋值 解析自动装配&#xff08;byname、bytype、 constractor、 Autowired&#xff09; 循环依赖 初始化 调用XXXAware回调方法&#xff08;BeanNameAware、BeanFactoryAw…

Java集合——Map、Set和List总结

文章目录 一、Collection二、Map、Set、List的不同三、List1、ArrayList2、LinkedList 四、Map1、HashMap2、LinkedHashMap3、TreeMap 五、Set 一、Collection Collection 的常用方法 public boolean add(E e)&#xff1a;把给定的对象添加到当前集合中 。public void clear(…

【Python】免费的图片/图标网站

专栏文章索引&#xff1a;Python 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 这里是我收集的几个免费的图片/图标网站&#xff1a; iconfont-阿里巴巴矢量图标库icon&#xff08;.ico&#xff09;INCONFINDER&#xff08;.ico&#xff09;