【C++】类和对象(上)

目录

1. 面向过程和面向对象初步认识

2.  类的引入

3. 类的定义

4. 类的访问限定符及封装

4.1 访问限定符

4.2 封装

5. 类的作用域

6. 类的实例化

7. 类对象模型

8. this指针

8.1 this指针的引出

8.2 this指针的特性


没有坚持的努力,本质上并没有多大意义!


1. 面向过程和面向对象初步认识

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

2.  类的引入

C 语言中,结构体中只能定义变量,在 C++ 中,结构体内不仅可以定义变量,也可以定义函数。就升级成了类。(类的关键字是class,类定义对象)
(1)结构体名称可以做类型
(2)结构体可以定义函数
class ListNode
{int _val;//struct ListNode* next;//c语言的方式,C++也兼容ListNode* _next;//C++的方式
};//因为struct被升级,结构体名称可以作类型
//这里的listNode我们叫做对象

命名规则建议:C++类的成员我们习惯在前面加一个_(来区分类的对象和别的参数)

3. 类的定义

class className
{// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号
class 定义类的 关键字, ClassName 为类的名字, {} 中为类的主体,注意 类定义结束时后面 分号
类中的元素称为 类的成员: 类中的 数据 称为 类的属性 或者 成员变量 ; 类中的 函数 称为 类的方法 或者 成员函数
类的两种定义方式:
1. 声明和定义全部放在类体中,需要注意:成员函数如果 在类中定义 ,编译器可能会将其当成 内联函数 处理。
2. 声明放在.h 文件中,类的定义放在 .cpp 文件中
一般情况下,更期望采用第二种方式。实际中,一般情况下,短小函数可以在类里面定义,长一点函数声明和定义分开。

4. 类的访问限定符及封装

4.1 访问限定符

C++ 实现封装的方式: 用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其 接口提供给外部的用户使用
class Date
{
public:void Init(int year){_year = year;}
private:int _year;
};
访问限定符:public、private、protected
1. public 修饰的成员在类外可以直接被访问
2. protected private 修饰的成员在类外不能直接被访问 ( 此处 protected private 是类似的 )
3. 访问权限 作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class 的默认访问权限为 private struct public( 因为 struct 要兼容 C)
注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
问题:C++中struct和class的区别是什么?
解答: C++ 需要兼容 C 语言,所以 C++ struct 可以当成结构体使用。另外 C++ struct 还可以用来定义类。和class定义类是一样的,区别是 struct 定义的类默认访问权限是 public class 定义的类默认访问权限是private。注意:在继承和模板参数列表位置, struct class 也有区别.

4.2 封装

【面试题】 面向对象的三大特性: 封装、继承、多态
在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互。

注意:(1)C语言数据和方法是分离的;而C++数据和方法封装到类里面,想让别人访问的部分设成公有,不想让别人访问的设成私有。

(2)一般情况下,类的成员数据都是私有或者保护。想给别人访问的函数是共有的,不想让别人访问的函数是私有或者保护。

(3)封装本质上是一种管理。

5. 类的作用域

类定义了一个新的作用域 ,类的所有成员都在类的作用域中 在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。(两个类里面可以有一样的变量和函数,因为类定义了一个新的作用域)
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " "<< _gender << " " << _age << endl;
}
//此时,这个函数的内容,相当于在类里面,所以可以用类中的对象(私有的也可以)

(1)在类里面定义的函数默认是inline函数。实际中,一般情况下,短小函数可以在类里面定义,长一点函数声明和定义分开。

(2)类成员变量仅仅只是声明。【声明没有开辟空间】

6. 类的实例化

用类类型创建对象的过程,称为类的实例化
1. 类只是 一个 模型 一样的东西,限定了类有哪些成员,定义出一个类 并没有分配实际的内存空间 来存储它
2. 一个类可以实例化出多个对象, 实例化出的对象 占用实际的物理空间,存储类成员变量
int main()
{Person._age = 100; // 编译失败:error C2059: 语法错误:“.”return 0;
}
Person 类是没有空间的,只有 Person 类实例化出的对象才有具体的年龄。
int main()
{Person man;//这里才给类定义空间man._age = 100; return 0;
}//这样才对

7. 类对象模型

类对象的存储方式: 只保存成员变量,成员 函数存放在公共的代码段
类中仅有成员函数和什么也没有:内存为:1byte【分配一字节,占位,表示类存在过】
结论:一个类的大小,实际就是该类中 ”成员变量”之和 ,当然也要进行内存对齐,注意空类的大小,空类比 较特殊,编译器给了空类一个字节来唯一标识这个类。
知识点复习:结构体内存对齐
1. 第一个成员在与结构体偏移量为 0 的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS 中默认的对齐数为 8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是
所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
【面试题】
1. 结构体怎么对齐? 为什么要进行内存对齐?
2. 如何让结构体按照指定的对齐参数进行对齐?
3. 什么是大小端?如何测试某台机器是大端还是小端,有没有遇到过要考虑大小端的场景

8. this指针

8.1 this指针的引出

class Date
{
public:void Display(){cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};
int main()
{Date d1, d2;d1.SetDate(2018, 5, 1);d2.SetDate(2018, 7, 1);d1.Printf();d2.Printf();return 0;
}
Date 类中有 SetDate 与Display 两个成员函数,函数体中没有关于不同对象的区分,那当 s1 调用 SetDate 函数时,该函数是如何知道应该设置s1 对象,而不是设置 s2 对象呢?【函数都在公共区,类的变量又不能访问,仅仅是一个声明】
C++ 中通过引入 this 指针解决该问题,即: C++ 编译器给每个 非静态的成员函数 增加了一个隐藏的指针参 数,让该指针指向当前对象 ( 函数运行时调用该函数的对象 ) ,在函数体中所有 成员变量 的操作,都是通过该 指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成

8.2 this指针的特性

 以上代码:(1)d1和d2地址,和分别对应的this是一致的。

(2)this不能修改,this指向的变量可以修改。

1. this 指针的类型:类类型 * const ,即成员函数中,不能给 this 指针赋值,不能修改。
2. 只能在 成员函数 的内部使用
3. this 指针本质上是 成员函数 的形参 ,当对象调用成员函数时,将对象地址作为实参传递给 this 形参。所以对象中不存储 this 指针
4. this 指针是 成员函数 第一个隐含的指针形参,一般情况由编译器通过 ecx 寄存器自动传递,不需要用 户传递

【面试题】
1. this 指针存在哪里?一般在栈区,有些编译器会使用寄存器优化,存放在寄存器。
2. this 指针可以为空吗?可以的,但是不能解引用变量,可以是函数(函数在公共区域)
class A
{
public:void Show(){cout << "Show()" << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->Show();//这个不是解引用,因为函数在公共区域,并不是在空指针的位置,所以不会报错}//正常运行
class A
{
public:void Show(){cout << "Show()" << endl;}int _a;
};int main()
{A* p = nullptr;p->Show();//这个不是解引用,因为函数在公共区域,并不是在空指针的位置,所以不会报错p->_a = 0;//这个是解引用,在类里,空指针,所以就会报错
}//运行崩溃
class A
{
public:void PrintA(){cout << _a << endl;//在这里进行空指针的解引用,报错}
private:int _a;
};int main()
{A* p = nullptr;p->PrintA();
}
//运行崩溃

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

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

相关文章

Git rebase和merge区别详解

文章目录 变基的基础用法变基过程中的冲突解决冲突后无法push问题更新变基后的代码更有趣的变基用法变基的风险用变基解决变基变基 vs 合并 此文在阅读前需要有一定的git命令基础&#xff0c;若基础尚未掌握&#xff0c;建议先阅读这篇文章Git命令播报详版 在 Git 中整合来自不…

封装动态SQL的插件

最近根据公司的业务需要封装了一个简单的动态SQL的插件&#xff0c;要求是允许用户在页面添加SQL的where条件&#xff0c;然后开发者只需要给某个接口写查询对应的表&#xff0c;参数全部由插件进行拼接完成。下面是最终实现&#xff1a; 开发人员只需要在接口写上下面的查询SQ…

JavaWeb项目工程结构介绍

介绍idea创建Web项目工程下的项目结构&#xff08;新建的web工程&#xff09; 了解目录大致作用 一级目录 :.idea、out、src、web、工程名.iml .idea目录&#xff1a;记录了IntelliJ IDEA 的配置目录&#xff0c;包含项目的配置信息、工程设置、构建配置等。它是用来存储项目…

C++ 派生类成员的标识与访问——作用域分辨符

在派生类中&#xff0c;成员可以按访问属性分为以下四种&#xff1a; &#xff08;1&#xff09;不可访问成员。这是从基类私有成员继承下来的&#xff0c;派生类或是建立派生类对象的模块都无法访问到它们&#xff0c;如果从派生类继续派生新类&#xff0c;也是无法访问的。 &…

Vue系列第七篇:Element UI之el-main,el-table,el-dialog,el-pagination,el-breadcrumb等控件使用

本篇实现主页面功能&#xff0c;包括主页面排版布局&#xff0c;学生管理模块实现&#xff0c;后台接口实现等功能。 目录 1.运行效果 1.1登录页面 1.2主页面 1.3学生管理 - 信息列表 1.4学生管理 - 信息管理 1.5学生管理 - 作业列表 1.6学生管理 - 作业管理 2.前端代码…

HDFS介绍

目录 ​编辑 一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块&#xff08;Block&#xff09; 1.3.2 复制…

Spring集成Junit

目录 1、简介 2、Junit存在的问题 3、回顾Junit注解 4、集成步骤 4.1、导入坐标 4.2、Runwith 4.3、ContextConfiguration 4.4、Autowired 4.5、Test 4.6、代码 5、补充说明 5.1、Runwith 5.2、BlockJUnit4ClassRunner 5.3、没有配置Runwith ⭐作者介绍&#xff1…

DROP USER c##xyt CASCADE > ORA-01940: 无法删除当前连接的用户

多创建了一个用户&#xff0c;想要给它删除掉 一 上执行过程&#xff0c;确实删除成功了 Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing optionsSQL> DR…

前端必知:38.对BFC的认识与理解

目录 什么是BFC BFC的特点 BFC 的布局规则 创建一个BFC的方法 什么是BFC BFC&#xff08;Block Formatting Context&#xff09;是 CSS 中的一个概念&#xff0c;用于描述页面中块级元素如何布局和相互影响的规则和上下文。BFC 是页面渲染时创建的一个独立的布局环境&…

OPENCV C++(一) 二进制和灰度原理 处理每个像素点值的方法

#include <opencv2/opencv.hpp> using namespace std; using namespace cv;必须包含的头文件&#xff01; 才能开始编写代码 读取相片 一般来说加个保护程序 不至于出error和卡死 Mat image imread("test.webp"); //存放自己图像的路径 if (image.empty()){p…

深入理解缓存 TLB 原理

今天分享一篇TLB的好文章&#xff0c;希望大家夯实基本功&#xff0c;让我们一起深入理解计算机系统。 TLB 是 translation lookaside buffer 的简称。首先&#xff0c;我们知道 MMU 的作用是把虚拟地址转换成物理地址。 MMU工作原理 虚拟地址和物理地址的映射关系存储在页表…

mysql二进制方式升级8.0.34

一、概述 mysql8.0.33 存在如下高危漏洞&#xff0c;需要通过升级版本修复漏洞 Oracle MySQL Cluster 安全漏洞(CVE-2023-0361) mysql/8.0.33 Apache Skywalking <8.3 SQL注入漏洞 二、查看mysql版本及安装包信息 [rootlocalhost mysql]# mysql -V mysql Ver 8.0.33 fo…

Cilium系列-13-启用XDP加速及Cilium性能调优总结

系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于: 启用本地路由(Native Routing)完全替换 KubeProx…

express学习笔记7 - docker跟mysql篇

安装Docker和Navicat Docker 进官⽹https://docs.docker.com/get-docker/ 选择机型安装即可。 Navicat&#xff08;也可以在网上找个破解版本&#xff09; 进官⽹https://www.navicat.com/en/products/navicat-premium 安装完之后连接新建⼀个数据库连接 然后再⾥⾯新建⼀个数…

zookeeper的部署

一 先下载zookeeper 二 解压包 三 修改配置文件 四 把配好文件传到其他的节点上面 五 在每个节点的dataDir指定的目录下创建一个 myid 的文件 六 配置zook的启动脚本 七 设置开机自启 八 分别启动 九查看当前状态service zookeeper status 十 总结 一 先下载zookeeper …

Zebec 创始人 Sam 对话社区,“Zebec 生态发展”主题 AMA 回顾总结

近日&#xff0c;Zebec Protocol 创始人 Sam 作为嘉宾&#xff0c;与社区进行了以“Zebec 生态发展”为主题的 AMA 对话。Sam 在线上访谈上对 Zebec 路线图、Zebec 质押、NautChain通证进行了解读&#xff0c;并对 Zebec 的进展、生态建设的愿景进行了展望。本文将对本次 AMA 进…

PtahDAO:全球首个DAO治理资产信托计划的金融平台

金融科技是当今世界最具创新力和影响力的领域之一&#xff0c;区块链技术作为金融科技的核心驱动力&#xff0c;正在颠覆传统的金融模式&#xff0c;为全球用户提供更加普惠、便捷、安全的金融服务。在这个变革的浪潮中&#xff0c;PtahDAO&#xff08;普塔道&#xff09;作为全…

【cluster_block_exception】写操作elasticsearch索引报错

【cluster_block_exception】操作elasticsearch索引b报错 背景导致原因&#xff1a;解决方法&#xff1a; 背景 今天线上elk的数据太多&#xff0c;服务器的空间不足了。所以打算删除一些没用用的数据。我是用下面的request&#xff1a; POST /{index_name}/_delete_by_query…

==和equals():比较对象等不等?

引言&#xff1a; 在编程中&#xff0c;我们常常需要判断两个对象是否相等。而在Java中&#xff0c;有两种常用的方法&#xff1a;使用""运算符和调用equals()方法。这两个方法有什么区别呢&#xff1f;它们又有哪些有趣的应用呢&#xff1f;让我们一起来探索一下吧&…

怎么维护好自己的电脑

你的电脑已经成为你工作、学习、娱乐的最佳工具之一&#xff0c;但是如果你不做好电脑维护工作&#xff0c;就可能面临着电脑变慢、蓝屏、崩溃等问题。在这篇文章中&#xff0c;我们将介绍10个电脑维护步骤&#xff0c;让你的电脑更加稳定&#xff01; 为什么需要电脑维护&…