C++语法规则1(C++面向对象 )

news2024/11/29 6:31:49

C++面向对象

面向对象的三大特征是继承,多态和封装,C++重面向对象重要的就是这些,我们下面通过一些简单的实例加以理解,从这小节开始,我们将开启新的编程旅途。与 C 语言编程的思想完全不同了,这就是 C++!理解概念和掌握这些编程方法对学习 C++有很大的好处。

类和对象

C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。

打个比方说明一下什么是类,比如有一条小狗,小狗有名字叫旺财,旺财的年龄是 2 岁,同时旺财会汪汪的叫,也能跑。我们统称狗这个为类,类是我们抽象出来的,因为狗不只有上面的属性,还有体重,毛发的颜色等等,我们只抽象出几种属性成一个类。具体到哪条狗就叫
对象。

从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象。

下面以自定义狗类介绍如何自定义类和如何使用对象。
在 Ubuntu 上编辑一个 03_class_dog_example 目录,在 03_class_dog_example 目录下新建一个 03_class_dog_example.cpp 文件,内容如下。

1 #include <iostream> 

2 #include <string> 

3 using namespace std; 

4 

5 class Dog 

6 { 

7 public: 

8 string name; 

9 int age; 

10 

11 void run() { 

12 cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl; 

13 } 

14 }; 

15 

16 int main() 

17 { 

18 Dog dog1; 

19 

20 dog1.name = "旺财"; 

21 dog1.age = 2; 

22 dog1.run(); 

23 

24 Dog *dog2 = new Dog(); 

25 

26 if (NULL == dog2) { 

27 return 0; 

28 } 

29 dog2->name = "富贵"; 
30 dog2->age = 1; 

31 dog2->run(); 

32 

33 

34 delete dog2; 

35 dog2 = NULL; 

36 return 0; 

37 } 

第 5 行,定义了一个 Dog 狗,定义类时,起的类名要尽量贴近这个类,让人一看就明白,您这个类是做什么的。

第 7 行,访问限定符 public(公有的),此外还有 private(私有的)和 protected(受保护的)。写这个的目的是为了下面我们要调用这些成员,不写访问限定符默认是 private。关于访问限定符,如果是初学者可能会难理解。简单的来说,访问限定符就是设置一个成员变量和成员函数的访问权限而已,初学者暂时不必要深究什么时候应该用 public 和什么时候应该用 private。

第 8 至 11 行,定义了一个字符串变量 name,整形变量 age。和一个方法 run()。我们在这个 run()里打印相应的狗名和狗的年龄。PS:string 是 C++的数据类型,方便好用,使用频率相当高。

第 18 行,从栈中实例化一个对象 dog1(可以随意起名字)。

第 20 至 22 行,为 dog1 的成员变量赋值,dog1 的 name 赋值叫“旺财”,年龄为 2 岁。然后调用 run()方法,打印 dog1 的相关变量的信息。

第 24 行,从堆中实例化对象,使用关键字 new 的都是从堆中实例化对象。

第 26 行,从堆中实例化对象需要开辟内存,指针会指向那个内存,如果 new 没有申请内存成功,p 即指向 NULL,程序就自动退出,下面的就不执行了,写这个是为了严谨。

第 29 至 31 行,和 dog1 一样,为 dog2 的成员赋值。

第 34 和 35 行,释放内存,将 dog2 重新指向 NULL。

如果没有语法错误,我们完全可以预测到打印的结果。我们学习 C 语言的结构体,类其实和结构类似,可以说类是结构体的升级版本。

执行下面的指令开始编译。

g++ 03_class_dog_example.cpp -o 03_class_dog_example 

编译完成后执行的结果如下。
在这里插入图片描述

通过上面的例子我们已经学习了什么是类,和什么是对象。以描述 Dog 为一类(抽象出来的),从 Dog 类中实例出来就是对象(实际事物)。对象拥有 Dog 类里的属性,可以从栈中实例化对象,亦可从堆中实例化对象。类的编写过程和对象的使用过程大致如上了。我们只需要理解这个步骤,明白类的定义和使用即可。

构造函数与析构函数

什么是构造函数?构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数出现在哪里?前面我们学过类,实际上定义类时,如果没有定义构造函数和析构函数,编译器就会生成一个构造函数和析构函数,只是这个构造和析构函数什么事情也不做,所以我们不会注
意到一点。

构造函数的特点如下:

(1) 构造函数必须与类名同名;
(2) 可以重载,(重载?新概念,后面学到什么是重载。);
(3) 没有返回类型,即使是 void 也不行。

什么是析构函数?与构造函数相反,在对象结束其生命周期时系统自动执行析构函数。实际上定义类时,编译器会生成一个析构函数。

析构函数的特点如下:

(1) 析构函数的格式为~类名();
(2) 调用时释放内存(资源);
(3) ~类名()不能加参数;
(4) 没有返回值,即使是 void 也不行。

下面我们通过简单的例子来说明构造函数和析构函数的使用。新建一个目录04_structor_example,编辑一个 04_structor_example.cpp 内容如下。

1 #include <iostream> 

2 #include <string> 

3 using namespace std; 

4 

5 class Dog 

6 { 

7 public: 

8 Dog(); 

9 ~Dog(); 

10 }; 

11 

12 int main() 

13 { 

14 Dog dog; 

15 cout<<"构造与析构函数示例"<<endl; 

16 return 0; 

17 } 

18 

19 Dog::Dog() 

20 { 

21 cout<<"构造函数执行!"<<endl; 

22 } 

23 

24 Dog::~Dog() 
25 { 

26 cout<<"析构函数执行!"<<endl; 

27 } 

我们还是以简单的狗类作为示例,定义一个狗类,把构造函数和析构函数写上。前面不是说会自动生成构造函数和析构函数的吗?注意是编译时,编译器生成的。当我们要使用构造函数和析构函数时需要我们自己在类里添加。

第 5 至第 10 行,定义了一个狗类,并在里面写了构造函数和析构函数。

第 14 行,使用 Dog 类实例化一个 dog 对象。

第 15 行,打印一句"构造与析构函数示例"。

第 19 至 22 行,类的函数可以在类里实现,也可以在类外实现,不过在类外实现时需要使用“::”,此时我们把类的构造函数定义在类的外面,打印一句"构造函数执行!"。

第 14 至 27 行,类的析造函数定义在类的外面,打印一句"析造函数执行!"。

执行下面的指令开始编译。

g++ 04_structor_example.cpp -o 04_structor_example 

编译完成后执行的结果如下。
在这里插入图片描述

其实执行的结果也是可以预测的,在对象实例化时会调用构造函数,所以 Dog()先执行,然后再在 main()函数里继续执行 cout<<“构造与析构函数示例”<<endl;。最后对象生命周期结束时才会执行析构函数。

2.2.1.2 this 指针

一个类中的不同对象在调用自己的成员函数时,其实它们调用的是同一段函数代码,那么成员函数如何知道要访问哪个对象的数据成员呢?

没错,就是通过 this 指针。每个对象都拥有一个 this 指针,this 指针记录对象的内存地址。

在 C++中,this 指针是指向类自身数据的指针,简单的来说就是指向当前类的当前实例对象。

关于类的 this 指针有以下特点:

(1) this 只能在成员函数中使用,全局函数、静态函数都不能使用 this。实际上,成员函数默认第一个参数为 T * const this。也就是一个类里面的成员了函数 int func(int p),func 的原型在编译器看来应该是 int func(T * const this,int p)。

(2) this 在成员函数的开始前构造,在成员函数的结束后清除。

(3) this 指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。

下面以简单的例子来说明 this 的用法。我们还是以狗类为例,按上面的 this 解释,this 只能够在成员函数使用,并可以指向自身数据。我们就可以写这样简单的例子来说明 this 的用法。

我们在 Qt 里也会遇到 this 这个东西,下面这个例子就很容易解释 Qt 里的 this 指针的用法。

新建一个目录 05_this_pointer_example,编辑一个 05_this_pointer _example.cpp 内容如下。

1 #include <iostream> 

2 #include <string> 

3 using namespace std; 

4 

5 class Dog 

6 { 

7 public: 

8 string name; 

9 void func(); 

10 }; 

11 

12 int main() 

13 { 

14 Dog dog; 

15 dog.func(); 

16 return 0; 

17 } 

18 

19 void Dog::func() 

20 { 

21 this->name = "旺财"; 

22 cout<<"小狗的名字叫:"<<this->name<<endl; 

23 } 

第 21 和 22 行,在类的成员函数里使用了 this 指针,并指向了类里的成员 name。先将 name赋值叫“旺财”,然后我们打印 name 的值。
当程序没有语法错误里我们可以预测打印的结果,就是“小狗的名字叫:旺财”。

执行下面的指令开始编译。

g++ 05_this_pointer_example.cpp -o 05_this_pointer_example 

程序执行的结果如下。
在这里插入图片描述

继承

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。

当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。在 Qt 里大量的使用了这种特性,当 Qt 里的类不满足自己的要求时,我们可以重写这个类,就是通过继承需要重写
的类,来实现自己的类的功能。

一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:

class derived-class: access-specifier base-class 

与类的访问修饰限定符一样,继承的方式也有几种。其中,访问修饰符 access-specifier 是 public、protected 或 private 其中的一个,base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier,则默认为 private。

下面来捋一捋继承的方式,例子都是以公有成员和公有继承来说明,其他访问修饰符和其他继承方式,大家可以在教程外自己捋一捋。这个公有成员和继承方式也没有什么特别的,无非就是不同的访问权限而已,可以这样简单的理解。

  1. 公有继承(public):当一个类派生继承公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。

  2. 保护继承(protected): 当一个类派生继承保护基类时,基类的公有和保护成员将成为派生类的保护成员。

  3. 私有继承(private):当一个类派生继承私有基类时,基类的公有和保护成员将成为派生类的私有成员。

下面我们还是以狗类为例,在 2.2.1 小节里我们定义的狗类,已经定义了 name,age 和 run()方法。假设我们不想重写这个狗类,而是新建一个 Animal 类,让狗类去继承这个 Animal 类。

假设是公有继承,那么我们是不是可以在狗类实例的对象里去使用继承 Animal 类里的成员呢?

带着这个疑问,我们使用下面的例子来说明。

新建一个目录 06_inherit_example,编辑一个 06_inherit_example.cpp 内容如下。

1 #include <iostream> 

2 #include <string> 

3 using namespace std; 

4 

5 /*动物类,抽象出下面两种属性, 

6 *颜色和体重,是每种动物都具有的属性 

7 */ 

8 class Animal 

9 { 

10 public: 

11 /* 颜色成员变量 */ 

12 string color; 

13 /* 体重成员变量 */ 

14 int weight;
15 }; 

16 

17 /*让狗类继承这个动物类,并在狗类里写自己的属性。 

18 *狗类拥有自己的属性 name,age,run()方法,同时也继承了 

19 *动物类的 color 和 weight 的属性 

20 */ 

21 class Dog : public Animal 

22 { 

23 public: 

24 string name; 

25 int age; 

26 void run(); 

27 }; 

28 

29 int main() 

30 { 

31 Dog dog; 

32 dog.name = "旺财"; 

33 dog.age = 2; 

34 dog.color = "黑色"; 

35 dog.weight = 120; 

36 cout<<"狗的名字叫:"<<dog.name<<endl; 

37 cout<<"狗的年龄是:"<<dog.age<<endl; 

38 cout<<"狗的毛发颜色是:"<<dog.color<<endl; 

39 cout<<"狗的体重是:"<<dog.weight<<endl; 

40 return 0; 

41 } 

第 21 行,Animal 作为基类,Dog 作为派生类。Dog 继承了 Animal 类。访问修饰符为 public(公有继承)。
执行下面的指令开始编译。

  
g++ 06_inherit_example.cpp -o 06_inherit_example 

编译完成执行的结果为如下。
在这里插入图片描述

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

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

相关文章

[Linux基础]history相关的环境变量设置

目录 背景 简介 命令操作 1. 语法&#xff1a; 2. 功能 3. 参数 环境变量设置 背景 工作中时常收到客户的反馈&#xff0c;我的系统什么也没干&#xff0c;就出现文件丢失&#xff0c;程序错误等等问题&#xff1b;我们在问题排查的时候查看history信息也是重要环节…

大数据导论、Apache ZooKeeper

目录标题1、数据与数据分析2、数据分析基本步骤3、大数据时代4、分布式技术5、 Apache ZooKeeper5.1 ZooKeeper 概述5.2 ZooKeeper 特性5.3 ZooKeeper 集群角色5.4 ZooKeeper 集群搭建5.5 ZooKeeper 数据模型1、数据与数据分析 数据分析是指用适当的统计分析方法对收集来的数据…

零基础小白如何自学网络安全成为顶尖黑客?

在成为黑客之前&#xff0c;你需要做两点准备&#xff1a; 1、学一门编程语言。学哪一门不重要&#xff0c;但你要参考一下下面的条例&#xff1a; C语言是Unix系统的基础。它&#xff08;连同汇编语言&#xff09;能让你学习对黑客非常重要的知识&#xff1a;内存的工作原理…

Go爬虫学习笔记(二)

3 进阶路线&#xff1a;如何深入学习Go语言&#xff1f; 时间与复利思维 一万小时定律 - MBA智库百科 (mbalib.com)&#xff1a;大量训练。 思维模型 类比&#xff1a;类比旧知识知识组块&#xff1a;将知识拆分知识体系&#xff1a;知识之间的联系&#xff1a;wiki、笔记双链…

漏洞分析丨cve-2012-0003

作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞&#xff0c;他是MIDI文件中存在的堆溢出漏洞。在IE6&#xff0c;IE7&#xff0c;IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。二、漏洞环境虚拟机调试工具目标软件辅助工具XP-SP3、KaliOD、IDAIE6Windbg组件gflags.exe三…

Java 不同路径

不同路径中等一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路径&#xff1f…

直播间与2位优秀创作者分享经历

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 昨天&#xff0c;卢松松的直播间好像又被推荐给了2.9万人观看&#xff0c;讲了一个小时后直播间的人数一直攀升&#xff0c;最终冲破了2万人大关。晚些时候&#xff0c;白杨SEO也来到了我的直播间&…

【数据结构】——树与二叉树

文章目录树二叉树二叉树的性质完全二叉树二叉树的存储遍历二叉树和线索二叉树6.4 树和森林哈夫曼树应用树 树的定义&#xff1a;树是以分支关系定义的层次结构。 D; 树(Tree)是n(n≥0)个结点的有限集。 R 数据关系 有且仅有一个特定的称为根(Root) 的结点 当n>1时&…

FCN网络介绍

目录前言一.FCN网络二.网络创新点前言 在图像分割领域&#xff0c;有很多经典的网络&#xff0c;如MASK R-CNN&#xff0c;U-Net&#xff0c;SegNet&#xff0c;DeepLab等网络都是以FCN为基础进行设计的。我们这里简单介绍一下这个网络。 一.FCN网络 FCN网络介绍   FCN 即全…

【学习笔记】人工智能哲学研究:《心智、语言和机器》

关于人工智能哲学&#xff0c;我曾在这篇文章里 【脑洞大开】从哲学角度看人工智能&#xff1a;介绍徐英瑾的《心智、语言和机器》 做过介绍。图片来源&#xff1a;http://product.dangdang.com/29419969.html在我完成了一些人工智能相关的工作以后&#xff0c;我再来分享《心智…

基于libco的c++协程实现(时间轮定时器)

在后端的开发中&#xff0c;定时器有很广泛的应用。 比如&#xff1a; 心跳检测 倒计时 游戏开发的技能冷却 redis的键值的有效期等等&#xff0c;都会使用到定时器。 定时器的实现数据结构选择 红黑树 对于增删查&#xff0c;时间复杂度为O(logn)&#xff0c;对于红黑…

【Unity趣味编程】——c++实现小球的自由移动

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

IOS APP Store发布流程

一、官网添加新版本 进入官网,点击左上角号&#xff0c;添加新版本 新增版本 -> 填写推广文本、更新内容 -> 点击存储 二、Xcode打包 苹果打包需要注意版本号、版本code不能与线上重复。 点击Xcode -> Product -> Archive&#xff0c;选择App Store 第二步选择导出…

移除元素问题解决方法------LeetCode-OJ题

问题&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 要求&#xff1a; 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改…

爆品分析第5期 | 一条视频带货3700+,这款斋月不锈钢厨具套装火了!

俗话说民以食为天&#xff0c;吃在任何一种文化中都占据重要的位置&#xff0c;要做出一道美味佳肴&#xff0c;除了食材、烹饪者的自身厨艺之外&#xff0c;还少不了一口好锅。新冠疫情以来&#xff0c;全世界范围内的封闭让很多人养成了居家做饭的习惯&#xff0c;不仅为厨具…

Spark高手之路1—Spark简介

文章目录Spark 概述1. Spark 是什么2. Spark与Hadoop比较2.1 从时间节点上来看2.2 从功能上来看3. Spark Or Hadoop4. Spark4.1 速度快4.2 易用4.3 通用4.4 兼容5. Spark 核心模块5.1 Spark-Core 和 弹性分布式数据集(RDDs)5.2 Spark SQL5.3 Spark Streaming5.4 Spark MLlib5.5…

玩转金山文档 3分钟让你的文档智能化

在上个月底&#xff0c;我们给大家推荐了金山轻维表的几个使用场景&#xff0c;社群中不少用户反响很好&#xff0c;对其中一些场景的解决方案十分感兴趣。但也有一些人表示&#xff0c;有些场景不知道如何实现&#xff0c;希望我们能提供模版/教程。这次我们将做一期热门模板盘…

案例20-内存长期占用导致系统变慢

一、背景介绍 本篇博客是对生产环境出现内存长期占用导致系统变慢的原因分析及总结。 现状&#xff1a; 系统出现了爬取加载慢的情况&#xff0c;核心服务的内存占用很高的情况。 如下图&#xff1a; 二、思路&方案 查询服务内存占用过高的原因&#xff1a; 1、服务启动…

再学C语言43:字符串表示和字符串I/O

字符串是以空字符&#xff08;\0&#xff09;结尾的char数组 在程序中定义字符串 1&#xff09;字符串常量 字符串常量&#xff08;字符串文字&#xff09;&#xff1a;位于一对双引号中的任何字符 双引号里的字符加上编译器自动提供的结束标志\0字符&#xff0c;作为一个字…

线程安全 List 效率测试

List 常见类以及各自优缺点可自行参考 https://blog.csdn.net/weixin_39883065/article/details/111197724 本机环境 java 版本&#xff1a;1.8.0_161 window 信息&#xff1a; 测试代码 下面通过代码测试 List 线程安全类 Vector、Collections.synchronizedList(List lis…