当前位置: 首页 > news >正文

类和对象(1)

文章目录

  • 1.面向过程和面向对象初步认识
  • 2.类的引入
  • 3.类的定义
  • 4.类的访问限定符和封装
    • 4.1访问限定符
    • 4.2封装
  • 5.类的作用域
  • 6.类的实例化
    • 6.2结构体内存对齐规则
  • 7.this指针
    • 7.2this指针的特性
  • 封装(补充)

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

C++面向对象但不纯面向对象。JAVA纯面向对象。
所以C++支持C和C++面向对象混编。
C面向过程,关注的是过程

2.类的引入

类和结构体的区别:

  1. 类里可以有数据:成员变量
  2. 类可以定义函数
  3. 可以写成ListNode,不需加struct。
    C struct ListNode是类型。
    C
//C++兼容C结构体的用法。
typedef struct ListNode
{int val;struct ListNode* next;
}LTN;

C++

//C++把结构体升级成类
struct ListNode//声明这是个类,struct关键字不能去掉
{int val;ListNode* next;//后面想用这个类型的时候可以去掉。
};

如何用类?
C数据和方法分离,C++方法可以在类的里面

struct Stack
{
//成员函数
//成员函数直接定义到类里面void Init(int n=4)//缺省值{a = (int*)malloc(sizeof(int) * n);if (nullptr == a){perror("malloc申请空间失败");return;}capacity = n;size = 0;}void Push(int x){//...a[size++] = x;}//成员变量int* a;int size;int capacity;
};
int main()
{Stack st;//对象//如何调用函数?st.Init(4);st.Push(1);st.Push(2);st.Push(3);st.Push(4);return 0;
}

C++可以用struct定义类,但更喜欢用class定义类。

3.类的定义

class className
{//类体:包括成员函数(类的方法)和成员变量(类的属性)
}//一定要注意后面的分号!!!!
  • class:定义类的关键字
  • className:类名
  • {}:类的主体
  • 类体中的内容:类的成员
    定义一个声明和定义分离的类。
    缺省参数生命和定义不能同时给,一般在声明给。
    Stack.h
#pragma once
#include <string.h>
#include <stdlib.h>
//类成员函数声明和定义分离
struct Stack
{//成员函数void Init(int n = 4);//缺省参数在声明给void Push(int x);//类的声明//成员变量int* a;int size;int capacity;
};

Stack.cpp

#include "Stack.h"
void Stack::Init(int n)//Stack告诉编译器Init不是全局函数,是栈这个类的成员函数
{a = (int*)malloc(sizeof(int) * n);//看栈这个类里有没有a这个成员变量if (nullptr == a){perror("malloc申请空间失败");return;}capacity = n;size = 0;
}
void Stack::Push(int x)
{//...a[size++] = x;
}

用class Stack却编不过,为什么呢?
此时要用到访问限定符。

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

4.1访问限定符

C++访问限定符有三种:公有保护和私有,现阶段保护和私有没有区别。共有及在类外可以直接访问。保护和私有在类里可以访问,类外不可访问。

公有保护私有
publicprotectprivate
  1. 访问限定符不会限定在类里面的访问,锁外面的人不锁里面的人。
  2. 类里面可以有多个访问限定符,限定从该访问限定符到下一个访问限定符出现时位置,如果没有下一个访问限定符则到}结束。
  3. class的默认访问限定符是私有,struct是公有(因为struct要兼容C)。所以上一文中报错了。
    实际生活中不希望默认,希望大家指清楚到底是私有还是公有。
    注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
#pragma once
#include <string.h>
#include <stdlib.h>
struct Stack
{
publicvoid Init(int n = 4);void Push(int x);
privateint* a;int size;int capacity;
};

大多数情况下成员变量都是私有的,成员函数不给别人用的是私有,给别人用的是公有。
C++中struct和class没有区别,但是struct可以像C语言去用。
Test.cpp

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;};
int main()
{Stack st;Date d1;d1.Init(2023, 2, 3);//调用函数,年月日被初始化return 0;
}

4.2封装

【面试题】:面向对象的三大特性:封装,继承,多态
封装:将下面的细节藏起来,本质是一种更好的管理。
C++的封装:将数据和方法都放在类里面去了,即当前封装的极限,并把自己想访问的定义成共有,不想的定义成私有和保护。

5.类的作用域

类定义出一个新的作用域(类域)。

class Person
{public:void PrintPersonInfo();private:char _name[20];char _gender[3];int _age;
};
void Person::PrintPersonInfo()//PrintPersonInfo属于Person这个类域
{cout<<_name<<" "<<_gender<<" "<<_age<<endl;//此时可以调用私有
}

6.类的实例化

即用类类型
声明即要定义这个函数或变量,这个变量的类型是什么,名称是什么,参数是什么,但实际这个变量没有出来。定义即把其实实在在在的空间给开出来(对于变量而言)。
类就像一个别墅的设计图,设计了细节,但不能住人,实例化即根据设计图建造出一栋栋别墅。
在这里插入图片描述

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}//函数的定义
private:int _year;int _month;int _day;//声明,没有开空间};

只需要计算成员变量的大小。

int main()
{//类对象实例化--开空间Date d1;//定义才是开空间,对于对象整体定义。//Date._year=1;//Date::year=0;//以上两种不可以,声明内不可存数据。//d1._year=1;//也不行,访问限定符是私有的。访问不了,访问的时候需要调用这个函数。改成公有就可以了。d1.Init(2023,9,12);//Init函数存在哪里呢?d1._year++;cout<<sizeof(d1)<<endl;//类对象大小要考虑内存对齐规则return 0;
}//输出12

为什么成员变量存在对象里面,成员函数不存在对象里面?
每个对象的成员变量不一样,需要独立存储。
每个对象调用的成员函数一样,放到共享公共区域(代码段)。
只需要计算成员变量的大小。

//类中既有成员变量,又有成员函数
class A1{
pubic:void f1(){}
private:int a;
};//sizeof(A1):4
//类中仅有成员函数
class A2{
public:void f2(){}
};//sizeof(A2):1//【考点】如果是0,A2 aa1;没有实例化,不能取地址
//类中什么也没有
class A3
{}//sizeof(A3):1,这一个字节用来进行占位,不存储有效数据,标识对象存在过,被实例化定义出来了。

没有成员变量的类都是一个字节

6.2结构体内存对齐规则

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

7.this指针

原来代码:

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}

编译器处理完:

class Date
{
public:void Init(Date*this,int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}

原来代码:

int main()
{Date d1;Date d2;d1.Init(2023, 2, 3);d2.Init(2022, 2, 3);return 0;
}

编译器处理完:

int main()
{Date d1;Date d2;d1.Init(&d1,2023, 2, 3);d2.Init(&d2,2022, 2, 3);return 0;
}

如果是d1调用,this是d1的地址,赋值给d1的年月日。
不可以自己去加。

//可以在类里使用this,但是实参和形参里不可以
cout<<this<<endl;
this->_year = year;
this->_month = month;
this->_day = day;
//一般不会这么写
  1. this存在哪里?–存在对象里面?答案❌。
    在栈上,因为他是形参,隐含的形参,不需要显示写,是编译器自己加的。/VS下通过ecx寄存器。
    程序进行编译,编译后成员变量存在对象里,实例化出一个对象,对象存在上。成员函数不要存在栈中,因为成员函数存在一个公共区域,编译的时候要确定call这个函数的地址,这个地址不在对象中去找,在代码段。因为函数的地址是这些指令的地址,这些指令是存在哪呢?存在于代码段。两个东西完全不一样,要从两个不同的角度理解。一个是指令,一个是指令运行过程中的相关数据。不要把两个东西混在一起。
    《深入理解计算机系统》——修炼内功

7.2this指针的特性

void func()
{cout<<this<<endl;cou<<"func()"<<endl;}
int main()
{
//编译报错 运行崩溃 正常运行Date* ptr=nullptr;ptr->func();//结果:正常运行ptr->Init(2023,9,12);//运行崩溃,用this去解引用了this->yearptr->_year;//会崩溃,因为_year在对象里面,到指针指向的对象去找,指针是一个空指针,相当于解引用。*ptr).func();//正常运行,ptr真正的意义是传递给this,所以也是正常运行,没有解引用这个行为Date::func();//不能这么调用,因为要传递this指针。没有this指针调用。
}

指针调用用箭头,有箭头不一定解引用。函数不在对象里。调用这个函数要call这个地址,这个地址在公共区域去找,公共区域:代码段。
成员函数不可以不用对象去调,直接func()。

  1. 受到类域的限制,一般都不在类域里面去找,只在全局去找。在全局找func找不到
  2. 告诉func是Date的成员函数,调用成员函数要传递this指针,所以没有解引用,但是ptr传递给了this指针(cout<<this<<endl;),所以this指针是一个空,但不会报错,只有发生了恶劣的行为才会报错。
  3. 会不会解引用,取决于要不要在对象中去找,而不是有没有这个符号。
    调用函数一共就需要两个动作,一个是传参,传this指针,一个是调用函数,这两个动作都不涉及要去解引用。
    成员函数不是成员对象。

封装(补充)

C语言和C++真正的区别:数据结构的实现与语言无关

CC++
数据和方法分离的都封装在类里面
名字繁琐简洁
数据访问自由不受限制控制访问方式。愿意给你访问的公有,不愿意私有
底层一样

封装在一起才能通过访问限定符限制。

相关文章:

类和对象(1)

文章目录 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符和封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化6.2结构体内存对齐规则 7.this指针7.2this指针的特性 封装&#xff08;补充&#xff09; 1.面向过程和面向对象初步认识 C面向对象但不纯面向…...

学会用命令行创建uni-app项目并用vscode开放项目

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 创建 uni-app 项目 命令行创建 uni-app 项目 编译和运行 uni-app 项目&#xff1a; 用 VS Code 开发 uni…...

java.lang.ClassCastException: android.os.BinderProxy cannot be cast to ...

项目开发遇到下面这个报错了&#xff01; 问题原因 直接说原因&#xff0c;就是因为进程间不能直接传递对象&#xff0c;应该传递该Binder对象的映射&#xff08;代理对象&#xff09;&#xff0c;所以类型转换就出错了。如果在同一个进程中&#xff0c;直接传递对象没有关系&a…...

AIGC(生成式AI)试用 3 -- 专业主题

何为专业&#xff1f; 主要研究某种学业或从事某种事业 我的理解可能是在某个方向、某个行业&#xff0c;专业的更靠谱、说了更算、表达的更晰&#xff0c;结果更有说服力 本次提问&#xff1a;你我的专业 生成式AI知道你我的专业吗&#xff1f;生成式AI如何诠释你…...

rsyslog-日志管理 logrotate-日志轮转

日志的管理的方式&#xff0c;以及怎么自己写一个管理日志的小脚本&#xff0c;其实也不能算脚本 管理日志的进程 rsyslogd&#xff1a;绝大部分日志记录&#xff0c;和系统操作有关&#xff0c;安全&#xff0c;认证sshd,su&#xff0c;计划任务at,cron… httpd/nginx/mysql: …...

类和对象续

目录 包 自定义包 包的访问权限控制 常见的包 Static成员 静态成员变量 静态成员方法 代码块 构造块 静态块 重写 继承 继承是啥&#xff1f; 父类成员访问 子类中访问父类成员变量 两者不同名 两者同名 子类中访问父类对的成员方法 super 子类构造方法 …...

SpringCloud:Feign实现微服务之间相互请求

文章目录 &#x1f389;欢迎来到Java学习路线专栏~SpringCloud&#xff1a;Feign实现微服务之间相互请求 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1f4dc;其他专栏&#xf…...

LeetCode 1359. Count All Valid Pickup and Delivery Options【动态规划,组合数学】1722

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

[杂谈]-从硬件角度理解二进制数

从硬件角度理解二进制数 文章目录 从硬件角度理解二进制数1、概述2、模拟电路3、数字电路4、逻辑电平5、TTL 器件的电压水平6、总结 1、概述 二进制数以 2 为基数系统表示&#xff0c;该系统只有两 (2) 个不同的数值&#xff0c;即 0 和 1。就像最常见的那样&#xff0c;十进制…...

Fast-DDS 服务发现简要概述

阅读本文章需要对DDS基础概念有一些了解&#xff0c;一些内容来自Fast-DDS官方文档&#xff0c;一些是工作中踩过的坑。 1. 服务发现阶段 满足OMG标准的DDS服务发现分为两部分&#xff0c;分别是: PDP(Participant Discovery Protocol 参与者发现协议)&#xff1a;参与者确认…...

基于spingboot的websocket订阅、广播、多人聊天室示例

概述 基于spingboot的websocket多人聊天系统。包括订阅&#xff0c;广播、点对点单人聊天&#xff0c;多人聊天室功能。 详细 一、运行效果 简单示例 广播 单人聊天 多人聊天室 二、相关代码 websocket配置 package com.iamgpj.demowebsocket.config;import com.iamgpj.d…...

Linux mac Windows三系统 局域网文件共享方法

主要工具&#xff1a; Samba是一个开源的软件套件&#xff0c;允许Linux系统与Windows系统之间共享文件和打印机。 一、首先是Linux共享的设置 ①安装 sudo apt-get install samba ②创建共享文件夹 sudo mkdir /home/share ③配置用户 sudo smbpasswd -a kequan ④修改…...

Java——比较器

引入的背景 我们知道基本数据类型的数据&#xff08;除boolean类型外&#xff09;需要比较大小的话&#xff0c;直接使用比较运算符即可&#xff0c;但是引用数据类型是不能直接使用比较运算符来比较大小的。那么&#xff0c;如何解决这个问题呢&#xff1f; 在Java中经常会涉…...

【数据结构】初识泛型

文章目录 一般的类和方法&#xff0c;只能使用具体的类型: 要么是基本类型&#xff0c;要么是自定义的类。这种限制对代码的束缚就会很大。所以我们引入了泛型。泛型&#xff0c;泛顾名思义就是广泛的意思。就是适用于许多许多类型。从代码上讲&#xff0c;就是对类型实现了参数…...

代码随想录--哈希--有效的字母异位词

给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true 示例 2: 输入: s "rat", t "car" 输出: false 说明: 你可以假设字符串只包含小写字母。…...

MySQL——数据的增删改

2023.9.12 本章开始学习DML (数据操纵语言) 语言。相关学习笔记如下&#xff1a; #DML语言 /* 数据操作语言&#xff1a; 插入&#xff1a;insert 修改&#xff1a;update 删除&#xff1a;delete */#一、插入语句 #方式一&#xff1a;经典的插入 /* 语法&#xff1a; insert …...

云服务器与http服务器

如何与http服务器建立连接&#xff08;客户端&#xff09;&#xff1f; http请求设计格式&#xff1a; 例子&#xff1a; 发送http请求 http数据响应格式&#xff1a; 接收http服务器返回的数据需要进一步进行字符串处理操作&#xff0c;提取有用的数据。...

golang教程 beego框架笔记一

安装beego 安装bee工具 beego文档 # windos 推荐使用 go install github.com/beego/bee/v2master go get -u github.com/beego/bee/v2masterwindows使用安装bee工具时碰到的问题&#xff1b; 环境配置都没有问题&#xff0c;但是执行官网的命令&#xff1a;go get -u github…...

【深度学习】Mini-Batch梯度下降法

Mini-Batch梯度下降法 在开始Mini-Batch算法开始之前&#xff0c;请确保你已经掌握梯度下降的最优化算法。 在训练神经网络时&#xff0c;使用向量化是加速训练速度的一个重要手段&#xff0c;它可以避免使用显式的for循环&#xff0c;并且调用经过大量优化的矩阵计算函数库。…...

AI项目六:WEB端部署YOLOv5

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 最近接触网页大屏&#xff0c;所以就想把YOLOV5部署到WEB端&#xff0c;通过了解&#xff0c;知道了两个方法&#xff1a; 1、基于Flask部署YOLOv5目标检测模型。 2、基于Streamlit部署YOLOv5目标检测。 代码在…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...