C++类与对象 (上)

目录

前言:

类和对象的理解

类的引入

类的定义与使用方式

访问限定符

类的两种定义方式

成员变量的命名规则

类的作用域

类的实例化

类对象模型

计算类对象的大小

类对象的存储方式

this指针


前言:

  • C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题;
  • C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成;

类和对象的理解

是一个抽象的概念,描述了一类对象的共同属性行为

对象是类的具体化,它是类的实例,具有类中定义的属性和行为;

在C++中,通常由数据成员成员函数组成,数据成员是类的属性,它们描述了对象的状态,成员函数是类的行为,它们描述了对象可以执行的操作,对象的创建是通过类的实例化来完成的,当程序需要使用类时,可以通过创建类的对象来使用类的属性和行为;

举例如下:

将“汽车”看作一个类,在这个类中定义了汽车的属性和行为,比如颜色、品牌、速度等属性,以及加速、刹车、转弯等行为;当我们要描述具体一辆汽车时,就需要创建一个该类的对象,并根据需要设置其相应的属性值或对其进行行为操作;

类的引入

由于C++兼容C语言中struct的所有用法,同时C++对关键字struct进行了升级,将struct升级为类;

  •  struct    类名 (类名即为变量类型)
//c语言
struct Stack
{int* a;int top;int capacity;
};
int main()
{//Stack s1; //C语言 ---> 未定义的标识符struct Stack s1;//只能采取带上struct关键字定义变量return 0;
}
//c++ 
struct Stack
{int* a;int top;int capacity;
};
int main()
{Stack s1;//可直接采取这种方案定义变量,不需要加上struct的关键字return 0;
}
//c语言定义链表结点
struct ListNode
{//ListNode* next;//C语言 ---> 未定义的标识符struct ListNode* next;int val;
};
//c++定义链表结点
struct ListNode
{ListNode* next;//编译通过int val;
};
  • C++结构体中可以定义函数;
//c++ 类里面可以定义函数
struct Stack
{int* a;int top;int capacity;//初始化栈void Init(){a = 0;top = 0;capacity = 0;}
};

 C++用关键字 class 代替 struct;

类的定义与使用方式

class 类名
{//类体: 由成员变量与成员函数组成}; //此处分号不可省略

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

访问限定符

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

 访问限定符说明:

  1. public修饰的成员类外可以直接被访问
  2. protected和private修饰的成员类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止;
  4. 如果后面没有访问限定符,作用域就到 } 即类结束;
  5. class的默认访问权限为privatestruct默认访问权限为public(因为struct要兼容C)
class Stack
{
private:int* a;int top;//a,top,capacity--->成员变量私有int capacity;//private的作用域从private开始到public,若没有public,直接到类结束;//由于class的默认访问权限为私有,省略掉private,三个成员变量依旧私有
public://初始化栈void Init()// Init()函数公有{a = 0;  top = 0;capacity = 0;}
}; //类结束

类定义的惯例:成员变量私有,成员函数公有;

class Stack
{
public:int* a;int top;int capacity;//初始化栈void Init(){a = 0;  top = -1;capacity = 0;}//空栈的判断bool StackEmpty(){return (top == -1);}
}; 
int main()
{Stack s1;s1.Init();//判断方式1:空栈, 若top=0,表示指向栈顶元素的下一个位置;//         空栈, 若top=-1,表示指向栈顶元素的位置;//栈的定义方式不同,如下判断方法可能导致出错;if (s1.top==0)//判断方式2:采取访问成员函数进行判断,直接调用判空函数,不会出错if (!s1.StackEmpty()){}//如上就是成员变量私有,成员函数公有的原因return 0;
}

类的两种定义方式

定义方式1:类的声明放在.h文件中,成员函数定义放在.cpp文件中;

                    (注:成员函数名前加 类名 ::)

定义方式2:声明和定义全部放在类体中;

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

成员变量的命名规则

class Date
{
public:void Init(int year,int month,int day){// 这里的year到底是成员变量,还是函数形参?year = year;//局部优先,year为函数形参//局部优先是指在函数内部创建了一个和全局变量同名的局部变量时;//函数内部对该变量的操作会优先作用于局部变量,而不会改变全局变量的值}
private:int year;int month;int day;
};

为了避免如上情形,C++采用成员变量前加 _

class Date
{
public:void Init(int year,int month,int day){_year = year;}
private:int _year;int _month;int _day;//year month day成员变量前加 _
};

类的作用域

定义了一个 新的作用域类的所有成员都在类的作用域中
类体外定义成员时,需要使用 ::作用域限定符指明成员属于哪个 类域
c++中由{ }所定义的皆为作用域;
class Stack
{//变量的声明,没有在内存中开辟空间int* a;int top;int capacity;
public:void Init();bool StackEmpty();
};
//需要指定Init()函数属于Stack类域
void Stack::Init()
{a = 0;top = 0;capacity = 0;
}

类的实例化

用类的类型创建对象的过程,称为类的实例化;
  1. 类是对对象进行描述的是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;
  2. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量
class Date
{
public:void Init(int year,int month,int day){_year = year;}int _year;int _month;int _day;
};
int main()
{Date::_year = 2023;//编译错误,成员变量为声明,没有开辟内存空间存储;// Date d; d.year=2023  //正确做法return 0;
}
//Date类是没有空间的,只有Date类实例化出的对象才有具体的年份

3. 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

类对象模型

类对象模型:类对象模型是指将类的成员函数和成员变量存储在一起的方式,这种方式将类的成员函数和成员变量封装在一个对象中,通过该对象来访问类的成员;

计算类对象的大小

# include <iostream>
using namespace std;
class Date
{
public:void Init(int year,int month,int day){_year = year;}int _year;int _month;int _day;
};
int main()
{Date d;cout << sizeof(d) << endl;return 0;
}
问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?

类对象的存储方式

类对象的存储方式:

对象中只保存成员变量,成员函数存放在公共代码段,这种方式将类的成员变量存储在对象中,而将成员函数存放在公共代码段中,通过对象来访问类的成员函数;

结论:一个类的对象大小,实际就是该类中”成员变量”之和,注意考虑内存对齐 ;

空类的大小:空类的大小为1字节;即使一个类没有任何成员变量和成员函数,它也会占用1字节的内存空间;

空的结构体大小:空的结构体大小为0字节,与空类不同,空的结构体不占用任何内存空间;

//类中仅有成员函数--->1byte
//对象中无成员函数
class B
{
public:void f2() {}
};
int main()
{B b;cout << sizeof(b) << endl;return 0;
}
//空类的大小 ---> 1byte
//无成员变量的类开辟1个字节,该字节不存储有效数据
//标识定义的对象存在过
class C
{};
int main()
{C c;cout << sizeof(c) << endl;return 0;
}

this指针

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;//日
};
int main()
{Date d1, d2;d1.Init(2023, 12, 17);d2.Init(2023, 12, 16);d1.Print();d2.Print();return 0;
}

运行结果:

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,d1调用的Print()函数与d2调用的Print()函数相同,那当d1调用Print()函数时,该函数是如何知道应该显示d1对象,而不是显示d2对象呢?
C++ 中通过引入 this指针 解决该问题,即: C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过该指针去访问;只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成

this指针的特性:

  1. this指针的类型类型* const 由于const修饰this,this指针不允许被修改;
  2. 只能在“成员函数”的内部使用 (不能显示的写实参和形参,但是可以在类中显示的使用);
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针
  4.  this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

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

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

相关文章

Day10 Liunx高级系统设计11-数据库2

DQL:数据查询语言 查询全表 select * from 表名; 查询指定列 select 列名 1, 列名 2,… from 表名 ; 条件查询 select * from 表名 where 条件 ; 注意&#xff1a; 条件查询就是在查询时给出 WHERE 子句&#xff0c;在 WHERE 子句中可以使用如下运算符及关键 字&#…

Zabbix监控系统部署与管理

目录 zabbix介绍 zabbix构成 zabbix进程 环境 zabbix-server节点部署 安装zabbix服务 安装与配置数据库 修改zabbix-PHP时区 登录网页安装 ​编辑数据库Access denied故障 zabbix-agent节点部署 zabbix web管理 中文乱码问题 zabbix介绍 zabbix是⼀个基于 Web 界…

【计算机网络】—— 详解码元,传输速率的计算|网络奇缘系列|计算机网络

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 码元 速率和波特 思考1 思考2 思考3 带宽&#xff08;Bandwidth&#xff09; &#x1f4dd;总结 码元…

十七、如何将MapReduce程序提交到YARN运行

1、启动某个节点的某一个用户 hadoopnode1:~$ jps 13025 Jps hadoopnode1:~$ yarn --daemon start resourcemanager hadoopnode1:~$ jps 13170 ResourceManager 13253 Jps hadoopnode1:~$ yarn --daemon start nodemanager hadoopnode1:~$ jps 13170 ResourceManager 15062 Jp…

Python开源项目周排行 2023年第40周

Python 趋势周报&#xff0c;按周浏览往期 GitHub,Gitee 等最热门的Python开源项目&#xff0c;入选的项目主要参考GitHub Trending,部分参考了Gitee和其他。排名不分先后&#xff0c;都是当周相对热门的项目。 入选公式&#xff1d;70%GitHub Trending20%Gitee10%其他 关注微…

Mapreduce小试牛刀(1)

1.与hdfs一样&#xff0c;mapreduce基于hadoop框架&#xff0c;所以我们首先要启动hadoop服务器 --------------------------------------------------------------------------------------------------------------------------------- 2.修改hadoop-env.sh位置JAVA_HOME配…

ubuntu安装详细步骤

一&#xff0c;先下载vmware 1&#xff0c;第一步打开上面链接 下载网址 : https://www.vmware.com/products/workstation-pro/wo rkstation-pro-evaluation.html 许可证 JU090-6039P-08409-8J0QH-2YR7F ZF3R0-FHED2-M80TY-8QYGC-NPKYF FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6 ZC3T…

StatusBar、NavigationBar窗口显示在Activity下面之aosp14窗口类bug线索征集

背景&#xff1a; hi&#xff0c;粉丝朋友们&#xff1a; 从上次帮助国际学员解决了一个分屏有黑屏的bug后&#xff0c;相关blog和解决方法 https://blog.csdn.net/learnframework/article/details/134708393 解决方法看b站视频&#xff1a; https://www.bilibili.com/video/B…

scala表达式

1.8 表达式&#xff08;重点&#xff09; # 语句(statement)&#xff1a;一段可执行的代码# 表达式(expression)&#xff1a;一段可以被求值的代码&#xff0c;在Scala中一切都是表达式 - 表达式一般是一个语句块&#xff0c;可包含一条或者多条语句&#xff0c;多条语句使用“…

基于YOLOv8深度学习的路面标志线检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

【AI基础设施】智算场景的资源管理系统与未来展望

高性能计算与智算场景 首先澄清两个概念&#xff0c;高性能计算与智算场景&#xff0c;高性能计算主要是面向天气预测、生物计算、材料计算等场景&#xff0c;而最近几年很火的智算主要是面向AI场景的计算&#xff0c;如语音识别、图像识别、自动驾驶等场景&#xff0c;我们可…

【C++11特性篇】一文助小白轻松理解 C++中的【左值&左值引用】【右值&右值引用】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.【左值&#xff06;左值引用】&…

广州华锐互动:VR煤矿特殊工种作业实训帮助提高矿工的操作技能和安全意识

VR煤矿特殊工种作业实训系统为煤矿企业培训提供了全方位的支持&#xff0c;帮助提高矿工的操作技能和安全意识&#xff0c;促进煤矿企业的安全生产。 首先&#xff0c;VR煤矿特殊工种作业实训系统可以提供逼真的虚拟操作环境&#xff0c;使矿工能够身临其境地感受各种工种的作业…

k8syaml提供的几个有意思的功能,Kubernetes在线工具网站

k8syaml.cn 提供的几个有意思的功能。 一、yaml资源快速生成 之前编写operator的helm的时候就需要自己写deployment、service、configmap这些资源&#xff0c;那么多字段也记不清&#xff0c;都是先找个模版&#xff0c;然后copy改改&#xff0c;再看官方文档&#xff0c;添加…

流程图、泳道图的介绍和示例分享,以及自定义元件库的介绍

目录 一. 流程图介绍 二. Processon使用 新建一个流程图 图形的使用 三. 流程图示例 登录界面 门诊业务流程图 住院业务流程图 药房业务流程图 会议OA流程图 四. 泳道图介绍 五. 自定义元件库 5.1 新建一个元件库 5.2 创建元件 5.3 使用自定义元件库 一. 流程图介…

初识SpringSecurity

目录 前言 特点 快速开始 导入依赖 运行项目 访问服务 权限控制 实现UserDetails接口 添加SecurityConfig配置类 测试接口DemoController 设置权限控制authorizeHttpRequests 结果分析 总结 前言 Spring Security是一个强大且高度可定制的身份验证和访问控制框架…

Openwrt源码下载出现“The remote end hung up unexpected”

最近项目原因需要下载openwrt21.02版本源码&#xff0c;花费了很多时间&#xff0c;找到正确方法后&#xff0c;发现可以节省很多时间&#xff0c;记录下过程&#xff0c;方便自己&#xff0c;可能方便他人。 一.问题阐述 openwrt21.02下载链接如下&#xff1a; git clone -…

提升数据分析效率:Amazon S3 Express One Zone数据湖实战教程

前言 什么是 Amazon S3&#xff1f;什么是 S3 Express One Zone&#xff1f;实现概述 技术架构组件实现步骤概览 第一步&#xff1a;构建数据湖的基础第二步&#xff1a;选择并查看数据集第三步&#xff1a;在 Athena 中搭建架构第四步&#xff1a;数据转换与优化第五步&#x…

Windows安装Elasticsearch并结合内网穿透实现公网远程访问

Windows安装Elasticsearch并结合内网穿透实现公网远程访问 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜…