c++的学习之路:5、类和对象(1)

一、面向对象和面向过程

在说这个定义时,我就拿c语言举例,在c语言写程序的时候,基本上就是缺什么函数,就去手搓一个函数,写的程序也只是调用函数的,而c++就是基于面向对象的开发,他关注的不再是单单的程序编写,在c语言编程过程中,我当时学习时,记得特别清楚的一句话就是,把这道题目分析一下,有几种情况,有什么极端条件,然后去根据问题写函数,在调用,就是一个面向过程的开发,而c++就是比较注重,把这个问题拆分成几块,中间有什么联系,去进行交互的,不需要关注类似于c语言的栈是怎么实现的,这个就是面向对象。

二、类的定义

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:
之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数,如下方代码所示,可以看出利用c语言创造结构体的方式可以在struct里面写一个函数,这就是一个类,但是c++兼容c所以可以这样写,但是c++一般喜欢利用class来表示这个类。

#include <iostream>
using namespace std;struct t
{int test1(){return 1;}
};int main()
{t t1;cout << t1.test1() << endl;return 0;
}

 如下图可以看出在我把struct换成class后编译就会报错,这是为啥?这是因为c++是面向对象的,在使用过程中肯定有一些不想让别人使用的东西,这时c++ 就提出了一个公有私有保护的概念,这里先介绍私有和公有,就是用两个英文单词中private和public一个是私人的,一个是公有的,就是在public后面就是别人可以访问的,在private后面就是不能访问的,如下方代码与图二所示可以看出,把函数放在公有区就可以正常访问了,而在这个类的里面虽然变量在后面,但是函数依然可以访问,在c++中类中函数与变量如果没定义的话,就会默认为私有。

  

class t
{
public:int test1(){return a+b;}
private:int a = 1;int b = 2;
};int main()
{t t1;cout << t1.test1() << endl;return 0;
}

还有我们定义变量名一般都不是abcd这样,最起码都是英文单词,例如data数据,但是在进行更改变量时,如下代码该咋办,会不会很不好,这时可以更改下变量名,例如mydata,但是一般都是使用_data,我看到很多书中都是这么写的代码,上网搜了下,才知道是为了区分自己代码中变量和别的地方别冲突,这样可读性就会变高,如下方第二个代码所示

class Test
{
public:
    
    void Test(int data)
    {
        data = data;
    }

private:
    int data;
};

class Test
{
public:

    void Test(int data)
    {
        _data = data;
    }

private:
    int _data;
};

三、类的限定符及封装

上文已经说了类是有私有和公有的,就是类的访问限定符,访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别,这里总的说一下有五点,如下:

1. public修饰的成员在类外可以直接被访问

2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)

3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

4. 如果后面没有访问限定符,作用域就到 } 即类结束。

5. class的默认访问权限为private,struct为public(因为struct要兼容C)

面向对象的三大特性:封装、继承、多态。在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。封装本质上是一种管理,让用户更方便使用类,简单来说就是我把类的函数放在一起,封装起来,你想用哪个我提供那个给你用。

四、类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::
作用域操作符指明成员属于哪个类域,这里最明显的就是声明与定义分离时,是最明显的,这里如下代码所示,就是一个明显的使用,在类外面定义函数时需要加上作用域操作符,要不会访问不到的。

class Test
{
public:
    void test();
private:
    int _data1;
    int _data2;
};

void Test::test()
{
    
}

五、类的实例化

用类创建对象的过程就是实例化,我想了感觉咋说都有点变扭,最后想出来,实例化就有点像我在这里存在过,这里说明这个类就是实实在在的占了内存的空间,就是和人一样存在这里,是一个实实在在存在的,这个就是实例化,就如下方代码T1就是利用Test创建了一个T1,这里就是一个实例化。

class Test
{
public:
    void test();
private:
    int _data1;
    int _data2;
};

void Test::test()
{
    
}

int main()
{
    Test T1;
    return 0;
}

六、类的对象模型

首先讲到这里肯定要计算下类的大小,这里类的计算就是只计算变量,不计算函数,这里的计算方式和c语言中的结构体计算一样就不过多解释了,对齐规则如下。

1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

类的函数时放在公共的代码段中,如果不是在代码段中,每一次创建类的时候就会非常占内存所以,这里就是放在代码段里面,然后每次都去调用。

七、tihs指针

比方说在一个类的传参中,是如何进行传参的?在c语言中是利用指针进行传参,这里只需要调用是什么原理,这时我看到了this指针,这个就是c++里面的在传参过程中,是编译器调用了一个指针,叫做this他就代表这个类,但是这指针我们可以定义吗,如下方代码可以看出这是个正常使用的并且正常打印了,结果如下图。

struct Test
{
public:void test(int data1, int data2){_data1 = data1;_data2 = data2;}void print(){cout << _data1 << ' ' << _data2 << endl;}
private:int _data1;int _data2;
};int main()
{Test T1;T1.test(1, 2);T1.print();return 0;
}

可是他是如何知道我要打印的是T1的数据呢,这时如果把this指针带上结果是啥?报错吗?可以看出下图输出正常。

 

可是如果把this定义在形参里还可以正常使用吗,可以看出结果是报错了,可以看出,他是有一个隐藏的指针this支持使用,但是不能定义。

最后说一下this指针的四个特性:

1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。

2. 只能在“成员函数”的内部使用

3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递 

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

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

相关文章

Python提示‘ModuleNotFoundError: No module named ‘numpy.core._multiarray_umath‘

一、问题背景 在学习Python编程使用matplotlib时&#xff0c;总是提示: ModuleNotFoundError: No module named numpy.core._multiarray_umath 问题大致描述如下&#xff1a; D:\WorkSpace\PythonWorkSpace\Python编程-从入门到实践\venv\Scripts\python.exe D:\WorkSpace\Pyt…

vue3+ts+element home页面侧边栏+头部组件+路由组件组合页面教程

文章目录 效果展示template代码script代码样式代码 效果展示 template代码 <template><el-container class"home"><el-aside class"flex" :style"{ width: asideDisplay ? 70px : 290px }"><div class"aside-left&q…

阿里云账号登录注册手机/支付宝/淘宝/钉钉看看哪个更简单?

阿里云账号登录或注册支持四种方式&#xff0c;即手机号验证码登录、支付宝、淘宝或钉钉登录&#xff0c;如果你没有阿里云账号&#xff0c;可以使用手机号接收短信验证码注册并登录&#xff0c;不过直接使用经常用的淘宝、支付宝或钉钉登录更为简单&#xff0c;因为可以免去实…

学浪视频提取

经过调查,学浪这个学习平台越来越多人使用了,但是学浪视频官方没有提供下载按钮,为了让这些人能够随时随地的观看视频,于是我钻研学浪视频的下载,终于研究出来了并且做成软件批量版 下面是学浪视频提取的软件,有需要的自己下载一下 链接&#xff1a;https://pan.baidu.com/s/…

ActiveMQ Artemis 系列| High Availability 主备模式(消息复制) 版本2.19.1

一、ActiveMQ Artemis 介绍 Apache ActiveMQ Artemis 是一个高性能的开源消息代理&#xff0c;它完全符合 Java Message Service (JMS) 2.0 规范&#xff0c;并支持多种通信协议&#xff0c;包括 AMQP、MQTT、STOMP 和 OpenWire 等。ActiveMQ Artemis 由 Apache Software Foun…

课堂练习:环境体验——3、Linux 权限管理

任务描述 本关任务&#xff1a;根据所学知识&#xff0c;完成文件权限的修改。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 如何创建和删除用户以及用户的权限管理&#xff1b;如何设置文件的访问权限。 Linux的权限管理主要分为两类&#xff1a;用户和…

Openmmalb InternLm2.0笔记

Openmmalb InternLm2.0浦语大模型全链路开源体系 文章目录 Openmmalb InternLm2.0浦语大模型全链路开源体系

机器学习——聚类算法-层次聚类算法

机器学习——聚类算法-层次聚类算法 在机器学习中&#xff0c;聚类是一种将数据集划分为具有相似特征的组或簇的无监督学习方法。聚类算法有许多种&#xff0c;其中一种常用的算法是层次聚类算法。本文将介绍聚类问题、层次聚类算法的原理、算法流程以及用Python实现层次聚类算…

Matplotlib数据可视化实战-2绘制折线图(2)

2.11营业额可视化 已知某学校附近一个烧烤店2022年每个月的营业额如下图所示。编写程序绘制折线图对该烧烤店全年营业额进行可视化&#xff0c;使用红色点画线连接每个月的数据&#xff0c;并在每个月的数据处使用三角形进行标记。 烧烤店营业额 月份123456789101112营业额/万…

Claude 3被玩出自我意识了?AI社区轰动,我们买会员来了次实测

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了人工智能中文站 每天给大家更新可用的国内可用chatGPT资源​ 更多资源欢迎关注 ​ Anthropic 发布了新一代大模型系列 Claude 3&#xff0c;遥遥领先快一年之久的 GPT-4 终于迎来了强劲的对手。 ​ Claude 3 …

yolov8 pose keypoint解读

yolov8进行关键点检测的代码如下&#xff1a; from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # pretrained YOLOv8n model# Run batched inference on a list of images results model([im1.jpg, im2.jpg]) # return a list of Results objects# Pr…

UE4_官方动画内容示例1.2_动画蓝图——使用蓝图告知Actor播放动画

展示了两个示例&#xff1a;在其中一个示例中&#xff0c;使用蓝图告知Actor播放动画&#xff0c;在另外一个示例中&#xff0c;展示了告知Actor播放动画的动画蓝图&#xff08;例如&#xff0c;此示例展示了如何将变量从蓝图传递给动画蓝图&#xff0c;并演示了如何将现有姿势…