C++之二:类和对象

相关代码:

C语言是面向过程的,关注的是过程,分析求解问题的步骤,调用函数逐步解决问题。

C++是面向对象的,关注的是对象,将一件事情的完成分为不同的几个参与者(对象),靠参与者的交互来完成任务。

一、类

C语言中,结构体只能用来定义变量;在C++中,结构体不仅可以定义变量,还可以定义函数

C++中更常用class来定义类

类体中内容称为类的成员:

  • 类中的变量称为类的属性或成员变量
  • 类中的函数称为类的方法或者成员函数

二、类的定义

类的两种定义方式:

1、声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

2、 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

3、定义一个类

// 定义一个数据结构栈的类
const int N = 10;
class Stack {
public:void Init() {_a = (int*)malloc(sizeof(int) * N);_top = 0;_capacity = N;}void Destory() {free(_a);_a = NULL;_top = -1;_capacity = 0;}void Push(int x) {if (_top == _capacity) {_capacity *= 2;int* tmp = (int*)realloc(_a, sizeof(int) * _capacity);if (tmp != nullptr) {_a = tmp;}}_a[++_top] = x;}void Pop() { _top--; }int Top() { return _a[_top]; }private:int* _a;int _top;int _capacity;
};

三、类的实例化

1、访问限定符

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

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

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

Q:C++中struct和class的区别是什么?

A:C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类默认访问权限是private。(C++的struct中也可以定义函数,C中的struct不能定义函数。C++中class和struct唯一的区别就是默认权限的不同)。

 2、封装

         面向对象的三大特性:封装、继承、多态

        封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

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

3、类实例化对象 

类实例化对象,相当于定义出了类的成员变量。

类,本质上就是一种自定义类型以及相应的操作函数)。

int main()
{//类实例化对象Stack st;st.Init();st.Push(1);cout << st.Top() << endl;st.Pop();st.Destory();return 0;
}
4、类的大小

        与C语言结构体类似,存在内存对齐(不了解的可看结构体那一章,内存对齐的规则)。但是类实例化的对象的大小只与成员变量有关,不存放函数。

	cout << sizeof(st) << endl;  //12

上述Stack类对象的大小占12Byte,这就说明,一个类实例化出的对象并没有存储成员函数。

原因:

1、一个类实例化出N个对象,每个对象的成员变量存储的值可以是不同的。

2、但是调用的函数是相同的代码

3、如果每个对象都存放成员函数,而这些成员函数是相同的。那么创建大量对象时,会浪费大量的空间。

4、因此:对象中只存放成员变量,而成员函数存放在公共代码段

没有成员变量的类大小是1Byte

class A2
{
public:void A_2(){}
};
class A3
{
};

Q:问什么没有成员变量的类的大小是1而不是0?

A:假设没有成员变量的类的大小是0。则当该类实例化一个对象,调用成员函数时,找不到实例化对象的地址,无法调用函数。因此,系统规定,没有成员变量的类的大小是1

 5、this指针

隐含的this指针:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数。

  1. 编译器让该指针指向当前对象,在函数体中所有“成员变量”的操作,都是通过该指针去访问。
  2. 只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
  3. this指针一定加载函数参数的第一个位置。(用户加不加都可以)。

怎么证明this指针确实存在?

        对于一个成员函数,在该函数内部,当我们调用相应的成员变量时,我们没有传入相应参数,而且成员函数与成员变量没有存放在同一区域,那我们为什么可以调用该成员变量呢?

有关this指针的一个问题:

//下面的代码可以正常运行吗?
class A4
{
public:void Print(){cout << /*this->*/_a << endl;//当传入this==nullptr时,产生访问冲突}void Show(){cout << "show()" << endl;}
private:int _a;
};int main()
{A4* p = nullptr;p->Show();	//正常运行p->Print();//编译能通过,但是程序崩溃,原因:访问空指针
}
// Show(A4* this);Print(A4* this)
// p->Show()  -->  Show(p);
//p->Print()  -->  Print(p);要访问空指针,

四、类的默认函数

默认成员函数:当用户没有实现时,编译器会自动生成的。(包括默认构造函数、默认析构函数)

1、构造函数

构造函数,在创建对象时调用的函数,完成初始化工作。(初始化对象)。

  1. 函数名与类名相同。
  2. 无返回值。(返回void也不行)。
  3. 对象实例化时编译器自动调用对应的构造函数。(实例化时自动调用)。
  4. 构造函数可以重载
  5. 如果没有构造函数,编译器会自动生成一个无参的默认构造函数。(显式定义后编译器不在生成)。
  6. 编译器自动生成的只会初始化自定义类型成员变量。(C++11在这里又有所修改)
  7. 无参的构造函数与全缺省的构造函数都称为默认构造函数,而默认构造函数只能有一个。(全缺省构造函数和无参构造函数不能同时存在)。

class Time
{
public:Time(){_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;Time _t;// 当Date没有构造函数时,会对Time调用构造函数初始化,对int型不初始化
};int main()
{Date d1;//调用编译器生成的构造函数d1.Print();return 0;
}
//我们没有显式定义构造函数,这里编译器会生成无参的默认构造函数//默认的构造函数:// 1、针对内置类型的成员变量没有初始化// 2、对自定义类型的成员变量,调用它的构造函数初始化 //构造函数,在对象构造时调用的函数,完成初始化工作/*Date(){//全缺省的构造函数和无参默认构造函数不能同时存在:存在歧义_year = 0;_month = 0;_day = 0;}Date(int year, int month, int day){_year = year;_month = month;_day = day;}*/Date(int year = 0, int month = 0, int day = 0)//更好的书写构造函数方式    -->    全缺省{_year = year;_month = month;_day = day;}

默认构造函数有三个无参构造函数、全缺省的构造函数、编译器自动生成的

三者共同的特点是:不需要传入参数就可以初始化

 2、析构函数

析构函数:对象生命周期到了以后,自动调用。

完成对象里面的资源清理工作,不是对d1和d2的销毁。

  1. 析构函数名是在类名前加上字符 ~
  2. 无参数无返回值类型
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
  5. 对于没有开辟动态内存的类,析构函数写不写都可以。
  6. 与构造函数类似,当使用编译器自动生成的析构函数时,只会析构自定义成员变量。

Q:为什么说析构函数是资源清理而不是销毁对象?

A:当成员变量中存在动态开辟的内存时,调用析构函数会释放这片空间,但是对象仍然存在,析构函数调用完后,对象的生命周期走到尽头,会被系统自动销毁。

	//析构函数:对象声明周期到了以后,自动调用。//完成对象里面的资源清理工作,不是对d1和d2的销毁~Date(){//没有参数也没有返回值cout << "~Date()" << endl;}

3、拷贝构造函数

拷贝构造函数:

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须是类实例化对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

了解引用之后,要记得C++对于传参有三种形式:

1、传值,(最浪费空间,而且不能修改原值)。

2、传址,(占用的空间与CPU位数有关,解引用修改原值)。

3、传引用,(不开辟空间,对引用的操作直接作用在原值)。

//const保证不通过d来修改d1
Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
Date d1(17,5,6);
Date d2(d1); //等价于d2 = d1 ,即拷贝构造函数
Date d3 = d1;

4、运算符重载函数

C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数

也具有返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名:关键字operator后面接需要重载的运算符符号
 

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

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

相关文章

B站bilibili视频转文字字幕下载方法

本文将讲述介绍一种使用本地工具如何快速的下载B站的字幕为本地文本文件的方法。 通常获取B站字幕需要在浏览器中安装第三方插件&#xff0c;通过插件获取字幕。随着大模型&#xff0c;生成式AI&#xff0c;ChatGPT的应用&#xff0c;B站也提供了AI小助手对视频的内容进行总结…

EM算法的参数更新过程

1. 计算每个高斯分布的责任度 责任度&#xff08;Responsibility&#xff09; 表示数据点 由第 k 个高斯分布生成的概率占总概率的比例。在 E步&#xff08;Expectation Step&#xff09; 中计算。 公式&#xff1a; 其中&#xff1a; ​: 责任度&#xff0c;表示数据点 ​ …

文件包含include

文件包含 第一道题是攻防世界的fileclude 这里第二行我们可以看见告诉我们在flag.php里面 然后检查了两次file1和file2是否为空 如果file2"hello ctf"成立 那么就可以包含file1 这里我们要使用php伪协议 来访问我们需要的flag.php并且将file2的数值改为"hello…

优选算法——链表

1. 链表常用技巧和操作总结 2. 两数相加 题目链接&#xff1a;2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 题目展示&#xff1a; 题目分析&#xff1a;本题给的是逆序&#xff0c;其实降低了难度&#xff0c;逆序刚好我们从第一位开始加&#xff0c;算法原理其实就…

【5G】5G的主要架构选项

最初&#xff0c;在3GPP讨论中考虑了所有可能的聚合和核心网络组合&#xff0c;共有八个架构选项。以下重点介绍option2、3、4和7。 1. 独立组网 (Standalone, SA) 架构选项 2 &#xff1a;Standalone architecture with 5G-core 特点&#xff1a; 5G核心网&#xff08;5GC, …

css 动画实现从中间到两边亮度逐渐变暗的流水灯效果

先看效果&#xff1a; 快结束效果 随着离中心点距离逐渐边远&#xff0c;亮度逐渐变暗 完整的视线代码如下&#xff1a; <template><div class"container"><div class"runner bottom to-right"></div><div class"runner …

kubeadm_k8s_v1.31高可用部署教程

kubeadm_k8s_v1.31高可用部署教程 实验环境部署拓扑图**部署署架构****Load Balance****Control plane node****Worker node****资源分配&#xff08;8台虚拟机&#xff09;**集群列表 前置准备关闭swap开启ipv4转发更多设置 1、Verify the MAC address and product_uuid are u…

测评|携程集团25年社招在线测评北森题库、真题分析、考试攻略

携程集团社招入职测评北森题库主要考察以下几个方面&#xff1a; 1. **言语理解**&#xff1a;这部分主要测试应聘者运用语言文字进行思考和交流、迅速准确地理解和把握文段要旨的能力。 2. **资料分析**&#xff1a;包括文字题和图表题&#xff0c;考察应聘者快速找出关键信息…

workman服务端开发模式-应用开发-websockt应用介绍

一、workerman介绍 1、框架介绍 workerman-chat框架是基于workerman的GatewayWorker框架开发的一款高性能支持分布式部署的聊天室系统。 workerman框架官网&#xff1a;http://www.workerman.net/ GatewayWorker框架文档&#xff1a;http://www.workerman.net/gatewaydoc/ 2、特…

34. 在排序数组中查找元素的第一个和最后一个位置 二分法

34. 在排序数组中查找元素的第一个和最后一个位置 class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {vector<int> res(2,-1);res[0]findleft(nums,target);if(res[0] -1) return res;res[1] findright(nums,target);…

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍03-SQL注入联合查询注入(Union-Based SQL Injection)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

你了解TCP/IP参考模型吗

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 你了解TCP/IP参考模型吗 一. TCP/IP参考模型二. TCP/IP模型图解三. TCP/IP模型的对比与OSI模型四. TCP/IP协议族五. 总结 TCP/IP参考…

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

RK3588 ,基于FFmpeg, 拉取RTSP,使用 mpp 实现硬解码. ⚡️ 参考: Rk3588 FFmpeg 拉流 RTSP, 硬解码转RGBUbuntu x64 架构, 交叉编译aarch64 FFmpeg mppCode RTSPint open_stream(

MySQL八股-全局锁,表级锁,表锁,元数据锁,意向锁,行级锁,行锁,间隙锁,临键

文章目录 全局锁表级锁表锁(表级锁)元数据锁(MDL&#xff0c;Meta Data Lock&#xff0c;表级锁)元数据锁演示元数据锁兼容的情况元数据锁互相阻塞的情况 意向锁&#xff08;Intention lock&#xff0c;表级锁&#xff09;意向锁分类意向锁演示&#xff1a;意向共享锁(**IS**)与…

【BUG记录】Apifox 参数传入 + 号变成空格的 BUG

文章目录 1. 问题描述2. 原因2.1 编码2.2 解码 3. 解决方法 1. 问题描述 之前写了一个接口&#xff0c;用 Apifox 请求&#xff0c;参数传入一个 86 的电话&#xff0c;结果到服务器 就变成空格了。 Java 接收请求的接口&#xff1a; 2. 原因 2.1 编码 进行 URL 请求的…

51c视觉~合集31

我自己的原文哦~ https://blog.51cto.com/whaosoft/12088488 #PDD 西南交大&利兹大学等联合提出金字塔离散扩散模型&#xff08;PDD&#xff09;&#xff0c;实现了3D户外场景生成的粗到细的策略 本文是对 ECCV 2024 Oral 文章Pyramid Diffusion for Fine 3D Large S…

strace跟踪的原理以及使用

如果想成为一名合格的工程师&#xff0c;那肯定应该知道如何去分析应用逻辑&#xff0c;对于如何优化应用代码提升系统性能也应该能有自己的一套经验。而今天想要讨论的是&#xff0c;如何拓展自己的边界&#xff0c;让自己能够分析代码之外的模块&#xff0c;以及对我自己而言…

Canoe CAPL编程

文章目录 CAPL 简介CAPL的程序结构CAPL的数据类型1. 无符号整数2. 有符号整数3. 有符号整数4. CAN消息类型5. 定时器类型6. 变量定义 on message xxx 中 this相关方法公共方法1. output(msgName) 从程序块输出message&#xff08;形式1&#xff09;或errorframe&#xff08;形式…

详解CompletableFuture

最近一直畅游在RocketMQ的源码中&#xff0c;发现在RocketMQ中很多地方都使用到了CompletableFuture&#xff0c;所以今天就跟大家来聊一聊JDK1.8提供的异步神器CompletableFuture&#xff0c;并且最后会结合RocketMQ源码分析一下CompletableFuture的使用。 Future接口以及它的…

HarmonyOS 非线性容器LightWeightMap 常用的几个方法

LightWeightMap可用于存储具有关联关系的key-value键值对集合&#xff0c;存储元素中key值唯一&#xff0c;每个key对应一个value。 LightWeightMap依据泛型定义&#xff0c;采用轻量级结构&#xff0c;初始默认容量大小为8&#xff0c;每次扩容大小为原始容量的两倍。 集合中k…