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

C++ | 面向对象 | 类

👻类

👾语法格式

class className{Access specifiers:				// 访问权限DataType variable;			// 变量returnType functions() { }	// 方法
};

👾访问权限

class className {public:// 公有成员protected:// 受保护成员private:// 私有成员
};

👽公有成员 public

公有成员在类外部可访问,可不使用任何成员函数来设置和获取公有变量的值

class Line {public:double length;void setLength(double len);double getLength(void);
};
double Line::getLength(void) { return length ; }
void Line::setLength(double len) { length = len; }...
Line line;
// 使用成员变量(正确,因为 length 公有) 
line.length = 10.0;
cout << line.length <<endl;
// 使用成员函数
line.setLength(6.0);
cout << line.getLength() <<endl;

👽私有成员 private

私有成员在类外部不可访问,不可查看,只有友元函数可以访问私有成员。没有使用任何访问修饰符默认私有。

class Box {public:double length;void setWidth(double wid);double getWidth(void);private:double width;
};
double Box::getWidth(void) { return width; }
void Box::setWidth( double wid ) { width = wid; }...
Box box;
// box.width = 10.0; 	// [Error] 'double Box::width' is private
box.setWidth(10.0);  	// 使用成员函数设置宽度
cout << box.getWidth() <<endl;

👽受保护成员 protected

受保护成员与私有成员相似,但有一点不同,受保护成员在**派生类(即子类)**中是可访问的。

/* 基类 */ 
class Box {protected:double width;
};/* 派生类 */
class SmallBox: Box {  public:void setSmallWidth(double wid);double getSmallWidth();
};
double SmallBox::getSmallWidth() { return width; }
void SmallBox::setSmallWidth(double wid) { width = wid; }...
SmallBox box;
box.setSmallWidth(5.0);
cout << box.getSmallWidth() << endl;

👻类成员函数

👾语法格式

  • 定义在类定义内部

    class className{returnType functions(parameter list) { ... }
    };
    
  • 单独使用范围解析运算符 :: 定义

    class className{returnType functions(parameter list);
    };
    returnType class_name::functions(parameter list){ ... }
    

👾示例代码

  • 定义在类定义内部

    class Box {public:double length;  // 长度double breadth; // 宽度double height;  // 高度double getVolume() { return length * breadth * height; }
    };
    
  • 单独使用范围解析运算符 :: 定义

    class Box {public:double length;  // 长度double breadth; // 宽度double height;  // 高度double getVolume();
    };double Box::getVolume() { return length * breadth * height; }
    

👻类构造函数

  • 类构造函数在每次创建类的新对象时执行。
  • 构造函数的名称与类的名称是完全相同的,不返回任何类型。
  • 构造函数可用于为某些成员变量设置初始值

👾无参构造函数

👽语法格式

class className{className() { ... }
};

👽示例代码

class Line {public:Line() { cout << "Object is being created" << endl; }private:double length;
};...
Line line;	// 输出:Object is being created

👾带参构造函数

👽语法格式

class className{className(parameter list) { ... }
};

👽示例代码

class Line {public:Line(double len) {length = len;cout << "Object is being created" << endl;}private:double length;
};...
Line line;	// 输出:Object is being created

👾初始化列表构造函数

👽语法格式

类有多个字段 A、B、C 等需要进行初始化:

class className{className(int a,int b,int c): A(a), B(b), C(c) { ... }
};

👽示例代码

class Line {public:Line(double len): length(len) { cout << "Object is being created" << endl; }private:double length;
};...
Line line;	// 输出:Object is being created

等同语法:

Line(double len) {length = len;cout << "Object is being created" << endl;
}

注意:初始化类成员时,是按声明的顺序初始化,而不是按初始化列表的顺序初始化,即:

class Base {public:// 按照 A -> B -> C 的顺序初始化int A;int B;int C;// 而不是按照 C -> B -> A 的顺序初始化Base(int a, int b, int c): C(c), B(b), A(a) {}
};

👻类析构函数

  • 类析构函数在每次删除所创建的对象时执行。
  • 析构函数的名称与类的名称是完全相同的,在前面加 波浪号(~) 作为前缀,不返回任何值,不能带有任何参数。
  • 析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源

👾语法格式

类有多个字段 A、B、C 等需要进行初始化:

class className{~className() { ... }
};

👾示例代码

class Line {public:Line() { cout << "Object created" << endl; }  // 构造函数声明~Line() { cout << "Object deleted" << endl; } // 析构函数声明
};...
Line line;

一个类内可以有多个构造函数(相当于重载构造函数),只有一个析构函数

class Matrix {public:Matrix(int row, int col);       //普通构造函数Matrix(const Matrix& matrix);   //拷贝构造函数Matrix();                       //构造空矩阵的构造函数~Matrix();
};

👻类拷贝构造函数

👾语法结构

class className{// obj是对象引用,用于初始化另一个对象className (const className &obj) { }
};
  • 参数 obj —— 本类的引用

    • const 类型引用 —— 既能以常量对象(初始化后值不改变的对象)作为参数,也能以非常量对象作为参数初始化其他对象

    • const 类型引用 —— 一般不使用

👾被调用情况

  • 情况1:用一个对象初始化同类的另一个对象时,调用被初始化的对象的拷贝构造函数

    Base a2(a1);	
    Base a2 = a1;
    
    class Base {public:int num;// 一般构造函数Base(int n) {num = n;cout << "General Constructor called" << endl;}// 拷贝构造函数Base(const Base& a) {num = a.num;cout << "Copy Constructor called" << endl;}
    };...// 只调用a1的一般构造函数,输出 General Constructor called
    Base a1(1);	
    // 只调用a2的拷贝构造函数,输出 Copy Constructor called
    Base a2(a1);	
    Base a2 = a1;
    // 不调用
    a2 = a1;		
    

    注意,Base a2 = a1; 是初始化语句,不是赋值语句。

    赋值语句的等号左边是一个早已有定义的变量,不会引发复制构造函数的调用,

    Base a1(1);	// 调用a1的一般构造函数
    Base a2(a1);	// 调用a2的拷贝构造函数
    a2 = a1;		// 不调用,因为 a2 早已生成且初始化,不会引发拷贝构造函数
    

    只会调用被初始化的对象的拷贝构造函数,不会调用其一般构造函数

  • 情况2:函数参数是类的对象,当函数调用时,调用对象的拷贝构造函数

    class Base {public:// 一般构造函数Base() { cout << "General Constructor called" << endl; };// 拷贝构造函数Base(Base& a) { cout << "Copy constructor called" << endl; }
    };
    void Function(Base a) {}...Base a;		// 调用a的一般构造函数,输出 General Constructor called
    Function(a);	// 调用a的拷贝构造函数,输出 Copy constructor called
    
    • 对象作为形参,函数被调用时,生成形参要用拷贝构造函数,会带来时间开销
    • 对象的引用作为形参,无时间开销,但有一定的风险,因为如果形参的值发生改变,实参值也会改变

    如果要确保实参值不改变,又希望避免拷贝构造函数的开销,解决办法是将形参声明为对象的 const 引用:

    void Function(const Base &a){...
    }
    
  • 情况3:函数返回值是类的对象,当函数返回时,调用对象的拷贝构造函数

    class Base {public:int num;// 一般构造函数Base(int n) {num = n;cout << "General Constructor called" << endl;}// 拷贝构造函数Base(const Base& a) {num = a.num;cout << "Copy constructor called" << endl;}
    };Base Func() {Base a(4);	// 调用一般构造函数,输出 General Constructor calledreturn a;
    }...int a = Func().num;	// 调用拷贝构造函数,输出 Copy constructor called
    

    有些编译器出于程序执行效率的考虑,编译时进行优化,函数返回值对象不用拷贝构造函数,不符合C++标准

👾深拷贝和浅拷贝

👽浅拷贝

  • 使用情况:基本类型数据、简单对象
  • 原理:按位复制内存
// 基本类型数据
int a = 10;
int b = a;
// 简单对象
class Base {public:Base(): m_a(0), m_b(0) { }Base(int a, int b): m_a(a), m_b(b) { }private:int m_a;int m_b;
};Base obj1(10, 20);
Base obj2 = obj1;

👽深拷贝

  • 使用情况
    • 持有其它资源的类(如动态分配的内存、指向其他数据的指针)
    • 标准模板库(STL)中 string、vector、stack 等
    • 创建对象时进行一些预处理工作,比如统计创建过的对象的数目、记录对象创建的时间等
  • 原理:显式定义拷贝构造函数
  • 过程
    • 会将原有对象的所有成员变量拷贝给新对象
    • 会为新对象再分配一块内存,并将原有对象所持有的内存也拷贝过来
  • 结果:原有对象和新对象所持有的动态内存相互独立,更改一个对象的数据不影响另一个对象
// 持有其它资源的类(如动态分配的内存、指向其他数据的指针)
#include <cstdlib>
#include <iostream>
using namespace std;class Array {public:Array(const int len) {m_len = len;m_p = (int*)calloc(m_len, sizeof(int));}Array(const Array& arr) {this->m_len = arr.m_len;this->m_p = (int*)calloc(this->m_len, sizeof(int));memcpy(this->m_p, arr.m_p, m_len * sizeof(int));}~Array() { free(m_p); }int operator[](int i) const { return m_p[i]; }int& operator[](int i) { return m_p[i]; }int length() const { return m_len; }private:int m_len;int* m_p;
};void printArray(const Array& arr) {int len = arr.length();for(int i = 0; i < len; i++) { if(i == len - 1) { cout << arr[i] << endl; } else { cout << arr[i] << ", "; } }
}...int main() {Array arr1(10);for(int i = 0; i < 10; i++)arr1[i] = i;Array arr2 = arr1;arr2[5] = 100;arr2[3] = 29;printArray(arr1); // 输出:0, 1, 2, 3, 4, 5, 6, 7, 8, 9printArray(arr2); // 输出:0, 1, 2, 29, 4, 100, 6, 7, 8, 9
}
// 创建对象时进行一些预处理工作
#include <iostream>
#include <ctime>
#include <windows.h>
using namespace std;class Base {public:Base(int a = 0, int b = 0) {m_a = a;m_b = b;m_count++;m_time = time(nullptr);}Base(const Base& obj) {this->m_a = obj.m_a;this->m_b = obj.m_b;this->m_count++;this->m_time = time(nullptr);}static int getCount() { return m_count; }time_t getTime() const { return m_time; }private:int m_a;int m_b;time_t m_time;      //对象创建时间static int m_count; //创建过的对象的数目
};int Base::m_count = 0;...int main() {Base obj1(10, 20);cout << "obj1: count = " << obj1.getCount() << ", time = " << obj1.getTime() << endl;// 输出:obj1: count = 1, time = 1740055359Sleep(3000);Base obj2 = obj1;cout << "obj2: count = " << obj2.getCount() << ", time = " << obj2.getTime() << endl;// 输出:obj2: count = 2, time = 1740055362return 0;
}

👻类静态成员

👾类静态成员变量

👽声明

使用 关键字 static 把类成员声明为静态

class Box {public:static int objectCount; // 声明静态变量Box() { objectCount++; } // 每次创建对象时调用构造函数,静态变量值加 1
};

无论创建多少个类的对象,静态成员只有一个副本,在类的所有对象中是共享的。

👽定义

在类外部通过 范围解析运算符 :: 定义静态变量

class Box {public:static int objectCount; // 声明静态变量Box() { objectCount++; } 
};
// 仅定义却不初始化 类静态成员
int Box::objectCount;

无论是否初始化,必须定义,否则报错:

(.rdata$.refptr._ZN3Box11objectCountE[.refptr._ZN3Box11objectCountE]+0x0): undefined reference to `Box::objectCount'

👽初始化

// 定义+初始化 类静态成员
int Box::objectCount = 0;

若不初始化,则在创建第一个对象时所有静态数据初始化为零

👽访问

  • 使用 范围解析运算符 :: 访问类静态变量
Box box1();    // 声明 box1
Box box2();    // 声明 box2
cout << "创建对象总数: " << Box::objectCount << endl;

👾类静态成员函数

👽声明定义

  • 使用 关键字 static 把类成员声明为静态
class Box {public:static int objectCount; // 声明静态变量Box() { objectCount++; }static int getCount() { // 声明定义静态函数return objectCount;}
};
  1. 普通成员函数有 this 指针,可以访问类中的任意成员
  2. 静态成员函数没有 this 指针,只能访问静态成员变量其他静态成员函数类外部的其他函数

👽使用

  • 使用 范围解析运算符 :: 访问类静态变量
cout << "创建对象总数: " << Box::getCount() << endl; // 对象不存在时 也能被调用
Box box1();    // 声明 box1
Box box2();    // 声明 box2
cout << "创建对象总数: " << Box::getCount() << endl;

静态成员函数即使 类对象不存在 也能被调用


👻友元

👾友元函数

  • 类的友元函数定义在类外部,但有权访问类的私有成员、保护成员
  • 尽管友元函数的原型在类的定义中出现,但友元函数不是成员函数

👽声明

使用 关键字 friend 把函数声明为友元函数

class Box {double width;public:Box(double w): width(w) {}friend void printWidth(Box box);  // 在函数前使用关键字 friend
};

👽定义

class Box {double width;public:Box(double w): width(w) {}friend void printWidth(Box box);
};/* printWidth() 不是任何类的成员函数,但因为它是 Box 的友元,可直接访问该类的任何成员 */
void printWidth(Box box) { cout << "Width of box : " << box.width <<endl;}

👽使用

Box box;
box.setWidth(10.0);
printWidth(box); 	// 使用友元函数访问Box中的私有成员

👾友元类

👽声明定义

class Box {public:Box(double w): width(w) {}friend class BigBox;private:double width;
};/* BigBox是Box的友元类,它可以直接访问Box类的任何成员 */
class BigBox {public :void printWidth(Box& box) { cout << "Width of box : " << box.width << endl; }
};

👽使用

Box box(10.0);
BigBox big;
big.printWidth(box); // 使用友元类中的方法访问Box中的私有成员

👻 this 指针

  • this 指针是一个特殊的指针,它指向当前对象的实例,每一个对象都能通过 this 指针来访问自己的地址。
  • 当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。
  • 友元函数没有 this 指针,因为友元不是类的成员
class MyClass {private:int value;public:// 可以明确地告诉编译器想访问当前对象的成员变量,而不是函数参数或局部变量,避免命名冲突void setValue(int value) { this->value = value; } void getValue() { return this->value; }
};...MyClass obj;
obj.setValue(42);
int value = obj.getValue();

相关文章:

C++ | 面向对象 | 类

&#x1f47b;类 &#x1f47e;语法格式 class className{Access specifiers: // 访问权限DataType variable; // 变量returnType functions() { } // 方法 };&#x1f47e;访问权限 class className {public:// 公有成员protected:// 受保护成员private:// 私有成员 }…...

性能测试分析和调优

步骤 性能调优的步骤 性能调优的步骤&#xff1a; 1.确定问题&#xff1a;根据性能测试的结果来分析确定bug。–测试人员职责 2.分析原因&#xff1a;分析问题产生的原因。----开发人员职责 3.给出解决方案&#xff1a;可以是修改软件配置、增加硬件资源配置、修改代码等----…...

阿里云oss文件上传springboot若依java

一、第一步 引入依赖 <!-- 阿里云OSS --> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId> </dependency> 二、第二步 application.yml #阿里云oss服务配置 aliyun:oss:endpoint: …...

【自学笔记】Oracle基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Oracle 数据库基础知识点总览1. 数据库安装与配置2. SQL基础3. PL/SQL基础4. 数据库管理5. 高级主题 总结 Oracle 数据库基础知识点总览 1. 数据库安装与配置 安装…...

使用create_sql_query_chain工具根据自然语言问题生成SQL查询,踩坑版

1. 开启调试模式 from langchain import debugdebug True # 启用调试模式说明&#xff1a; 这里从 langchain 库中导入了一个名为 debug 的变量&#xff08;或模块&#xff09;&#xff0c;然后将它设置为 True。这通常用来启用调试模式&#xff0c;方便开发者在程序运行时看…...

PyInstaller 打包python 程序 成 可执行文件

pyinstaller --onefile --name my_project --add-data "config/config.json:config" main.py 要将整个 Python 项目打包成一个可执行文件&#xff0c;可以使用 PyInstaller 来完成这个任务。以下是如何将整个项目打包成可执行文件的步骤&#xff1a; 1. 安装 PyIns…...

生鲜行业智能化供应链解决方案技术白皮书

行业痛点与技术挑战 损耗控制难题 行业平均损耗率达18%-25%&#xff0c;需构建动态定价模型与智能分拣系统 冷链管理复杂度 全程温控数据采集点超过23个/车次&#xff0c;异常响应延迟需压缩至90秒内 供需预测偏差 传统模式预测准确率不足65%&#xff0c;亟需AI驱动需求预测体…...

preg_replace 与 str_replace 的比较与选择

preg_replace 与 str_replace 的比较与选择 ——PHP字符串处理的核心工具深度解析 一、核心功能定位 在PHP的字符串处理中&#xff0c;str_replace和preg_replace是两种最常用的替换函数&#xff0c;但其设计目标和应用场景存在本质差异&#xff1a; str_replace 简单字符串替…...

无人机自主导航与避障技术!

自主导航的实现 环境感知&#xff1a;通过传感器&#xff08;如摄像头、激光雷达、超声波传感器等&#xff09;获取周围环境信息。 地图构建&#xff1a;利用SLAM&#xff08;同步定位与地图构建&#xff09;技术&#xff0c;实时生成环境地图并确定无人机的位置。 路径规划…...

密码学(哈希函数)

4.1 Hash函数与数据完整性 数据完整性&#xff1a; 检测传输消息&#xff08;加密或未加密&#xff09;的修改。 密码学Hash函数&#xff1a; 构建某些数据的简短“指纹”&#xff1b;如果数据被篡改&#xff0c;则该指纹&#xff08;以高概率&#xff09;不再有效。Hash函数…...

深入探索 STM32 微控制器:从基础到实践

一、引言 在当今的嵌入式系统领域&#xff0c;STM32 系列微控制器凭借其高性能、低功耗、丰富的外设以及广泛的应用场景&#xff0c;成为了众多开发者的首选。无论是在工业控制、智能家居、医疗设备&#xff0c;还是在消费电子等领域&#xff0c;STM32 都展现出了强大的生命力…...

React 常见面试题及答案

记录面试过程 常见问题&#xff0c;如有错误&#xff0c;欢迎批评指正 1. 什么是虚拟DOM&#xff1f;为什么它提高了性能&#xff1f; 虚拟DOM是React创建的一个轻量级JavaScript对象&#xff0c;表示真实DOM的结构。当状态变化时&#xff0c;React会生成新的虚拟DOM&#xf…...

SpringSecurity 实现token 认证

配置类 Configuration EnableWebSecurity EnableGlobalMethodSecurity(prePostEnabledtrue) public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { Bean Override public AuthenticationManager authenticationManagerBean() throws Exception {return s…...

【详解 | 辨析】“单跳多跳,单天线多天线,单信道多信道” 之间的对比

文章目录 1. 单跳 & 多跳2. 单天线 & 多天线3. 单信道 & 多信道4. 小区内通信 & 小区间通信5. 更多辨析5.1 无线Mesh网络&#xff0c;Ad Hoc网络&#xff0c;无线传感器网络&#xff08;MSN&#xff09;5.2 “单天线/多天线”与“单信道/多信道”的区别 6. 工业…...

嵌入式开发工程师笔试面试指南-HR面试常见问题汇总

在嵌入式领域的招聘面试中,HR 通过一系列精心设计的问题,全面考察候选人的综合素质、专业能力以及与岗位的匹配度。以下从多个关键方面汇总了 HR 在嵌入式面试中常见的问题。 ** 一、语言表达方面 请简单介绍一下你自己这是面试开场常见问题,旨在让候选人做一个自我展示,…...

Docker 搭建 Gitlab 服务器 (完整详细版)

参考 Docker 搭建 Gitlab 服务器 (完整详细版)_docker gitlab-CSDN博客 Docker 安装 (完整详细版)_docker安装-CSDN博客 Docker 日常命令大全(完整详细版)_docker命令-CSDN博客 1、Gitlab镜像 # 查找Gitlab镜像 docker search gitlab # 拉取Gitlab镜像 docker pull gitlab/g…...

MongoDB安全管理

MongoDB如何鉴权 保证数据的安全性是数据库的重大职责之一。与大多数数据库一样&#xff0c;MongoDB内部提供了一套完整的权限防护机制。如下例所示&#xff1a; mongo --host 127.0.0.1 --port 27017 --username someone --password errorpass --authenticationDatabasestor…...

架构案例:从初创互联网公司到分布式存储与反应式编程框架的架构设计

文章目录 引言一、初创互联网公司架构演化案例1. 万级日订单级别架构2. 十万级日订单级别架构3. 百万级日订单级别架构 二、分布式存储系统 Doris 架构案例三、反应式编程框架架构案例总结 引言 分布式架构 今天我们将探讨三种不同类型的架构案例&#xff0c;分别探讨 一个初…...

神经网络之CNN图像识别(torch api 调用)

1.简介 CNN 是受生物学上感受野机制启发而提出的。它通过卷积操作自动提取数据中的特征&#xff0c;避免了传统机器学习方法中复杂的特征工程过程&#xff0c;能够自动学习到数据中的有效特征&#xff0c;从而进行分类、识别等任务。 2.结构 2.1卷积&#xff1a; 假设你有一…...

使用Truffle、Ganache、MetaMask、Vue+Web3完成的一个简单区块链项目

文章目录 概要初始化Truffle项目创建编写合约编译合约配置Ganache修改truffle-config.js文件编写迁移文件部署合约使用Truffle 控制台使用MetaMask和VueWeb3与链交互 概要 使用Truffle、Ganache、MetaMask、VueWeb3完成的一个简单区块链项目。 初始化Truffle项目 安装好truf…...

学生管理前端

文章目录 首页student.html查询功能 首页 SpringBoot前端html页面放在static文件夹下&#xff1a;/src/main/resources/static 默认首页为index.html&#xff0c;我们可以用两个超链接或者两个button跳转到对应的页面。这里只是单纯的跳转页面&#xff0c;不需要提交表单等其…...

DeepSeek 助力 Vue3 开发:打造丝滑的网格布局(Grid Layout)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

lvgl运行机制分析

lv_timer_handler() 是 LVGL 的“心脏”&#xff1a;这个函数会依次做以下事情&#xff1a; 处理定时器&#xff08;如动画、延迟回调&#xff09;。 读取输入设备&#xff08;如触摸屏、按键的状态&#xff09;。 刷新脏区域&#xff08;仅重绘屏幕上发生变化的区域&#xf…...

ffmpeg avformat_open_input的作用

1. avformat_open_input 的作用 avformat_open_input 是 FFmpeg 中用于打开输入文件或输入设备的函数。它的主要作用是初始化输入文件或设备的上下文&#xff08;AVFormatContext&#xff09;&#xff0c;并准备好从输入源读取数据。 2. avformat_open_input 的功能 打开输入文…...

leaflet扩展插件esri-leaflet.js

esri-leaflet.js是一个开源的JavaScript库&#xff0c;它允许开发者在Leaflet地图上轻松地使用Esri的服务&#xff0c;如ArcGIS Online和ArcGIS Server的图层。以下是对esri-leaflet.js插件的详细介绍&#xff1a; 一、主要功能 esri-leaflet.js的主要功能是将Esri的地图服务…...

8 SpringBoot进阶(上):AOP(面向切面编程技术)、AOP案例之统一操作日志

文章目录 前言1. AOP基础1.1 AOP概述: 什么是AOP?1.2 AOP快速入门1.3 Spring AOP核心中的相关术语(面试)2. AOP进阶2.1 通知类型2.1.1 @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行(通知的代码在业务方法之前和之后都有)2.1.2 @Before:前置通知,此…...

day01_Java基础

文章目录 day01_Java基础一、今日课程内容二、Java语言概述&#xff08;了解&#xff09;1、Java语言概述2、为什么要学习Java语言3、Java平台版本说明4、Java特点 三、Java环境搭建&#xff08;操作&#xff09;1、JDK和JRE的概述2、JDK的下载和安装3、IDEA的安装4、IDEA的启动…...

cursor 弹出在签出前,请清理仓库工作树 窗口

问题出现的背景&#xff1a;是因为我有两台电脑开发&#xff0c;提交后&#xff0c;另一个电脑的代码是旧的&#xff0c;这个时候我想拉取最新的代码&#xff0c;就会出现如下弹窗&#xff0c;因为这个代码暂存区有记录或者工作区有代码的修改&#xff0c;所以有冲突&#xff0…...

详解直方图均衡化

直方图均衡化&#xff08;Histogram Equalization&#xff09; 是图像处理中一种常用的对比度增强技术&#xff0c;通过调整图像的灰度分布&#xff0c;使得图像的直方图尽可能均匀分布&#xff0c;从而提高图像的对比度和细节表现。以下是直方图均衡化的原理详解&#xff1a; …...

MyBatis-Plus 自动填充功能

MyBatis-Plus&#xff08;MP&#xff09; 提供了一个非常强大的功能——自动填充功能。该功能可以在执行插入或更新操作时&#xff0c;自动为某些字段赋值&#xff0c;免去手动设置这些字段的麻烦。常见的应用场景包括 创建时间 和 更新时间 字段的自动填充&#xff0c;帮助开发…...