C++类与对象(一)—学习记录

news2025/1/16 21:23:46

        序言:要想开发一款成功的应用程序,其开发者必须充分了解并实现用户的需求。作为一个设计良好的类,既要有直观且易于使用的接口,也必须具备高效的实现过程。


一、类与对象基本概念

        面向对象程序设计的主要特点为抽象封装继承多态,而类是面向对象程序设计方法的核心概念。类的基本思想是问题抽象和封装,问题抽象是一种依赖于接口和实现分离的编程(以及设计)技术,封装则实现类的接口和实现分离且隐藏实现细节[1-2]

        问题抽象,包括数据抽象行为抽象。数据抽象是为了描述某类对象的属性或状态,行为抽象是为了描述某类对象的共同行为或功能特征。

        封装,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体。换言之,将数据与操作数据的函数代码进行整合并形成“类”,其中的数据和函数都是类的成员。

注意事项与编码规范:

1. 类本身就是一个作用域,类的成员函数的定义嵌套在类的作用域之内;

2. 定义在类内部的函数是隐式的inline函数(内联函数较于普通函数可以减少调用的开销、提高执行效率,但会增加编译后代码的长度);

3. 一般来说,如果非成员函数是类接口的组成部分,则这些函数的声明应该与类在同一个头文件内。

二、类的基本构成

(一)构造函数

        在定义对象的时候进行的数据成员设置,称为对象的初始化。构造函数是类的一个成员函数,其特点有:函数名与类名相同,没有返回值,公有访问,其作用就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。一个类可以包含多个构造函数(函数重载),不同的构造函数之间必须在参数数量或参数类型上有所差异。

        如果类中没有写构造函数,编译器会自动生成一个隐含的默认构造函数,该构造函数的参数列表和函数体皆为空(在建立对象时自动调用构造函数是C++程序“例行公事”的必然行为)。对于默认构造函数而言,如果存在类内的初始值即用此初始化成员,否则默认初始化该成员(赋空值)。

        形如 Sales_data(const std::string &s):bookNo(s){}; 的对象初始化方式,":"以及":"与”{}“之间的代码称为构造函数初始值列表。构造函数初始值列表的作用是为新创建的对象的一个或几个数据成员赋初值。构造函数初始值是成员名字的一个列表,每个名字后面紧跟括号括起来的(或者在花括号内的)成员初始值。不同成员的初始化通过逗号分隔开来[2-p238]

注意事项:

1. 在C++11新标准中,如果需要显式默认构造函数,在类内可以通过 类名()=default; 方式实现;

2. 编译器只有在发现类不包含任何构造函数的情况下才会自动生成一个默认的构造函数。一旦定义了一些其他的构造函数,除非再次定义一个默认的构造函数,否则类将没有默认构造函数;

3. 如果类包含有内置类型或者复合类型(如数组或指针)的成员,则只有当这些成员全都被赋予了类内的初始值时,这个类才适合于使用合成的默认构造函数;

4. 有的时候编译器不能为某些类合成默认构造函数。例如,如果类内包含一个其他类类型的成员且这个成员的类型没有默认构造函数,那么编译器将无法初始化该成员。

(二)复制构造函数

        复制构造函数是一种特殊的构造函数,具有一般构造函数的所有特性,其形参是本类的对象的引用。其作用是使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象。

        复制构造函数会被调用的三种情况:

        1.  当用类的一个对象去初始化该类的另一个对象时;

        2. 如果函数的形参是类的对象,调用函数时,进行形参和实参结合时(只有把对象用值传递才会调用复制构造函数。引用传递则不会调用复制构造函数);

        3. 如果函数的返回值是类的对象,函数执行完成返回调用者时。

注意事项:

1. 如果没有定义类的复制构造函数,系统就会在必要时自动生成一个默认的复制构造函数。这个隐含的复制构造函数会把初始值对象的每个数据成员的值都复制到新建立的对象中;

2. 当类的数据成员中有指针类型时,默认的复制构造函数实现的只能是浅复制。浅复制会带来数据安全方面的隐患,要实现正确的复制,也就是深复制,必须编写复制构造函数。

(三)析构函数

        析构函数与构造函数的作用几乎正好相反,它用来完成对象被删除前的一些清理工作。析构函数是在对象的生存期即将结束的时刻被自动调用的,完成调用后,对象相应的内存空间也被释放。

        析构函数是类的一个公有函数成员,它的名称是由类名前面加”~“构成,没有返回值。和构造函数不同的是析构函数不接收任何参数,但可以是虚函数。如果不进行显式说明,系统也会生成一个函数体为空的默认析构函数。

注意事项:

1. 很多需要动态内存的类应该使用vector对象或者string对象管理必要的存储空间。使用vector或者string的类能避免分配和释放内存带来的复杂性,因为如果类包含vector或者string成员,则其拷贝、赋值和销毁的编译器自动合成版本函数能够正常工作;

2. 如果希望程序在对象被删除之前的时刻自动完成某些事情,就可以把它们写到析构函数中。

(四)访问控制与封装

1、访问控制属性  

        对类成员访问权限的控制,是通过设置成员的访问控制属性而实现的。访问控制属性可以有以下3种:公有类型(public)、私有类型(private)和保护类型(protected)。

        公有类型成员定义了类的外部接口,在类外只能访问类的公有成员。私有成员只能被本类的成员函数访问,来自类外部的任何访问都是非法的。保护类型成员的性质和私有成员的性质相似,其差别在于继承过程中对产生的新类影响不同。

2、友元 

        类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元(friend)。如果类想把一个函数作为它的友元,只需要增加一条以friend关键字开始的函数声明语句即可。

        友元声明只能出现在类定义的内部,但是在类内出现的具体位置不限。友元不是类的成员,也不受它所在区域访问控制级别的约束。

3. 封装的益处

        (1)确保用户代码不会无意间破坏封装对象的状态;

        (2)被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码。

三、结构体(Struct)和联合体(Union)

(一)结构体

        C++中引入结构体是为了保持和C程序的兼容性。C语言只有结构体而没有类,C语言的结构体中只允许定义数据成员,不允许定义函数成员,而且C语言没有访问控制属性的概念,结构体的全部成员是公有的。

        结构体可以使用{实际参数}进行初始化,这是一种聚合初始化的方式(类必须构造函数)。编译器会按照成员声明的顺序,将{}中的值依次赋给结构体的成员变量。具体形式如下:

struct aClass {int aa;int bb;int cc;};

aClass aa = {1,2,3};

(二)联合体

        联合体从C语言继承而来,默认访问控制属性也是公有类型。联合体的全部数据成员共享同一组内存单元,其成员同时至多只有一个是有意义的(即不能同时存储多个成员的值)。

        在给Union中的某个成员赋值后,其他成员的值将被覆盖;Union的字节存储大小由其最大字节存储大小的成员决定;Union可以在定义时直接初始化,但只能对第一个定义成员进行初始化[3]

联合体限制[1]

①联合体的各个对象成员,不能有自定义的构造函数、自定义的析构函数和重载的复制赋值运算符,不仅联合体的对象成员不能有这些函数,这些对象成员的对象成员也不能有,以此类推。

②联合体不能继承,因而也不支持包含多态。

Union定义初始化测试结果图

参考资料:

[1]  C++语言程序设计 / 郑莉,董渊,何江舟编著.—4版.—北京:清华大学出版社,2010.7(清华大学计算机系列教材)

[2] C++ Primer中文版:第5版 /(美)李普曼(Lippman,S.B.),(美)拉乔伊(Lajoie,J.),(美)默(Moo,B.E.)著;王刚,杨巨峰译. —北京:电子工业出版社,2013.9.

[3] Union:联合体的使用与理解-百度开发者中心

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

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

相关文章

【React】新建React项目

目录 create-react-app基础运用React核心依赖React 核心思想:数据驱动React 采用 MVC体系package.jsonindex.html好书推荐 官方提供了快速构建React 项目的脚手架: create-react-app ,目前使用它安装默认是19版本,我们这里降为18…

Jmeter数据库

jmeter之操作数据库 一、下载jdbc 驱动,安装jdbc驱动 2、将驱动存放在4个路径下 (1)C:\Program Files\Java\jre1.8.0_60\lib (2)第二个存放的包 C:\Program Files\Java\jre1.8.0_60\lib\ext (3&#xf…

nginx: [emerg] bind() to 0.0.0.0:80 failed 端口被占用

nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions) 查看被占用的端口 被系统占用了 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP 然后再进入nginx文件夹目录下…

《C++11》深入剖析正则表达式库:解锁文本处理的高效之道

在现代编程领域,文本处理是一项不可或缺的任务,而正则表达式无疑是这一领域的强大利器。C11标准库的引入,为C开发者带来了正则表达式库,极大地丰富了C在文本处理方面的能力。本文将全方位、多角度地深入探讨C11正则表达式库&#…

c语言----------内存管理

内存管理 目录 一。作用域1.1 局部变量1.2 静态(static)局部变量1.3 全局变量1.4 静态(static)全局变量1.5 extern全局变量声明1.6 全局函数和静态函数1.7 总结 二。内存布局2.1 内存分区2.2 存储类型总结2.3内存操作函数1) memset()2) memcpy()3) memmove()4) memcmp() 2.4 堆…

机器学习-归一化

文章目录 一. 归一化二. 归一化的常见方法1. 最小-最大归一化 (Min-Max Normalization)2. Z-Score 归一化(标准化)3. MaxAbs 归一化 三. 归一化的选择四. 为什么要进行归一化1. 消除量纲差异2. 提高模型训练速度3. 增强模型的稳定性4. 保证正则化项的有效…

STC的51单片机LED点灯基于KEIL

前言: 该文源于回答一个朋友的问题,代码为该朋友上传,略作修改,在此说明问题以及解决问题的思路,以减少新手错误。 电路图: 该位朋友未上传电路图,说明如下: stc8g1k08a-sop8控制…

手撕Transformer -- Day6 -- DecoderBlock

手撕Transformer – Day6 – DecoderBlock 目录 手撕Transformer -- Day6 -- DecoderBlockTransformer 网络结构图DecoderBlock 代码Part1 库函数Part2 实现一个解码器Block,作为一个类Part3 测试 参考 Transformer 网络结构图 Transformer 网络结构 DecoderBlock 代…

【功能测试总结】

功能测试 1. 功能测试用例1.1 设计用例容易出现的问题 2. 如何写用例2.1 什么是好的用例2.2 测试用例设计常见方法 3. 用例分级 1. 功能测试用例 1.1 设计用例容易出现的问题 基础功能点用例覆盖不全/描述不清 描述不清 什么是正常内容,仅看用例能否知道该输入什么…

Mac玩Steam游戏秘籍!

Mac玩Steam游戏秘籍! 大家好!最近有不少朋友在用MacBook玩Steam游戏时遇到不支持mac的问题。别担心,我来教你如何用第三方工具Crossover来畅玩这些不支持的游戏,简单又实用! 第一步:下载Crossover 首先&…

基于Springboot + vue实现的旅游网站

🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…

题解 CodeForces 430B Balls Game 栈 C/C++

题目传送门: Problem - B - Codeforceshttps://mirror.codeforces.com/contest/430/problem/B翻译: Iahub正在为国际信息学奥林匹克竞赛(IOI)做准备。有什么比玩一个类似祖玛的游戏更好的训练方法呢? 一排中有n个球…

Vue3播放视频报ReferenceError: SharedArrayBuffer is not defined

解决办法 前端本地测试vue.config.js server: {headers: {"Cross-Origin-Opener-Policy": "same-origin","Cross-Origin-Embedder-Policy": "require-corp",}, }, 后端vue.js生产环境 跨域隔离 是一种现代Web安全策略,…

Android BottomNavigationView不加icon使text垂直居中,完美解决。

这个问题网上千篇一律的设置iconsize为0,labale固定什么的,都没有效果。我的这个基本上所有人用都会有效果。 问题解决之前的效果:垂直方向,文本不居中,看着很难受 问题解决之后:舒服多了 其实很简单&…

微调神经机器翻译模型全流程

MBART: Multilingual Denoising Pre-training for Neural Machine Translation 模型下载 mBART 是一个基于序列到序列的去噪自编码器,使用 BART 目标在多种语言的大规模单语语料库上进行预训练。mBART 是首批通过去噪完整文本在多种语言上预训练序列到序列模型的方…

基于32QAM的载波同步和定时同步性能仿真,包括Costas环的gardner环

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印): 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 载波同步是…

设计模式-工厂模式/抽象工厂模式

工厂模式 定义 定义一个创建对象的接口,让子类决定实列化哪一个类,工厂模式使一个类的实例化延迟到其子类; 工厂方法模式是简单工厂模式的延伸。在工厂方法模式中,核心工厂类不在负责产品的创建,而是将具体的创建工作…

【机器学习】零售行业的智慧升级:机器学习驱动的精准营销与库存管理

我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 在当今数字化浪潮汹涌澎湃的时代,零售行业正站在转型升级的十字路口。市场竞争的白热化使得企业必须另辟蹊径&#xff0…

day_2_排序算法和树

文章目录 排序算法和树排序算法算法稳定性排序算法☆ 冒泡排序冒泡思路冒泡步骤代码实现效率优化 ☆ 选择排序排序思路排序步骤代码实现 ... 树01-树的基本概念02-树的相关术语03-二叉树的种类04-二叉树的存储05-树的应用场景_数据库索引06-二叉树的概念和性质07-广度优先遍历0…

蓝桥杯刷题第二天——背包问题

题目描述 有N件物品和一个容量是V的背包。每件物品只能使用一次。第i件物品的体积是Vi价值是Wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数,N,V&am…