C++核心编程——类和对象(一)

本专栏记录C++学习过程包括C++基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下,不定时更新,欢迎关注
当前章节处于:
---------第1阶段-C++基础入门
---------第2阶段实战-通讯录管理系统,
=====>第3阶段-C++核心编程
---------第4阶段实战-基于多态的企业职工系统
---------第5阶段-C++提高编程
---------第6阶段实战-基于STL泛化编程的演讲比赛
---------第7阶段-C++实战项目机房预约管理系统

文章目录

  • 一、 封装
    • 1.1 封装基本概念
    • 1.2 访问权限
    • 1.3 成员属性设置成私有
  • 二、对象特性
    • 2.1 对象的初始化和清理
    • 2.2 构造函数的分类与调用
    • 2.3 构造函数调用规则
    • 2.4 浅拷贝与深拷贝
    • 2.5 初始化列表
    • 2.6 类对象作为类成员
    • 2.7 静态成员
  • 三. C++对象模型和this指针
    • 3.1 成员变量和成员函数分开存储
    • 3.2 this指针概念
    • 3.3 空指针访问成员函数
    • 3.4 const修饰成员函数

类和对象是C++的核心,C++面向对象的三大特性:封装、继承、多态,C++认为万事万物都是对象,对象尤其属性和行为。

一、 封装

1.1 封装基本概念

封装是C++面向对象三大特性之一,意义在于:

  • 将属性和行为作为一个整体,表现生活中的事务
  • 将属性和行为加以权限控制

语法
class 类名{ 访问权限:属性/ 行为};
代码举例说明,设计一个圆类,计算圆的周长:

#include <iostream>
using namespace std;
#define PI 3.14
class Circle {// 权限
public://属性int r = 0;// 行为double getLength() {return r * r * PI;}
};int main() {// 实例化对象Circle c1;c1.r = 3;cout << "圆的周长为:" << c1.getLength() << endl;system("pause");return 0;}
圆的周长为:28.26
请按任意键继续. . .

创建类后需要实例化,才可以使用,相当于类是一个模具,实例化出来的对象才是产品。

#include <iostream>
using namespace std;
class Student {// 权限
public:// 属性string name;string cardnum;// 行为string getname() {return name;}string getcardnum() {return cardnum;}
};int main() {// 实例化对象Student stu;stu.name = "张三";stu.cardnum = "123";cout << "姓名为:" << stu.getname() << "    学号为:" << stu.getcardnum() << endl;system("pause");return 0;}
姓名为:张三    学号为:123
请按任意键继续. . .

1.2 访问权限

访问权限分为三种:

  • public 公共权限:类内可以访问,类外可以访问
  • protected 保护权限 类内可以访问,类外不可以访问
  • private 私有权限类内可以访问,类外不可以访问

protected和private区别在于继承时,儿子可以继承父亲中的protected内容,不可以继承父亲中private中内容

#include <iostream>
using namespace std;
class Person {
public:string name;
protected:string car;
private:string password;
public:void test() {// 类内都可以访问name = "张三";car = "自行车";password = "12345";}
};int main() {Person p1;p1.name = "李四";// 类外可以访问// p1.car; // 类外不可访问// p1.password;// 类外不可访问system("pause");return 0;}

struct也可以定义类,但是struct默认权限是公共权限,而class默认权限是公有;

#include <iostream>
using namespace std;
class test1 {// 默认私有int a = 0;
};
struct test2 {// 默认公共int b = 0;
};int main() {test1 test_1;test_1.a = 10; // 不能访问test2 test_2;test_2.b = 20; // 可以访问system("pause");return 0;}

1.3 成员属性设置成私有

优点在于:

  1. 将所有成员属性设置成私有,可以自己控制读写权限
  2. 对于写权限,可以检测数据的有效性

通过get和set方法进行访问和赋值

#include <iostream>
using namespace std;class Student {// 权限
private:// 属性string name="张三"; // 可读可写string cardnum="123";// 只读int score=0; // 只写
public:// 可读可写void setname(string inputname) {name = inputname;}string getname() {return name;}// 只读string getcarnum() {return cardnum;}// 只写void setscore(int inputscore) {score = inputscore;}
};
int main() {Student stu;cout << stu.getname() << endl;stu.setname("李四");cout << stu.getname() << endl;system("pause");return 0;}
张三
李四
请按任意键继续. . .

可以用get和set方法进行值的合法性判断。
练习案例1:设计立方体类

  • 设计立方体类(Cube)
  • 求出立方体的表面积和体积
  • 分别用全局函数和成员函数判断两个立方体是否相等

全局函数需要传入两个实例化对象,成员函数只要传入一个实例化对象即可

#include <iostream>
using namespace std;
class Cube {
public:double x=0.0f; // 边长double y=0.0f; // 边长double z=0.0f; // 边长void setinf(double inputx, double inputy, double inputz) {x = inputx;y = inputy;z = inputz;}int getS() {return 3 * (x * y+x*z+y*z);}int getV() {return x * y * z;}bool judge(Cube c2) {if ((c2.x == x)&&(c2.y==y)&&(c2.z==z)){return true;}else {return false;}}
};
// 定义全局函数
bool g_judge(Cube c1, Cube c2) {if ((c2.x == c1.x) && (c2.y == c1.y) && (c2.z == c1.z)) {return true;}else {return false;}
}
int main() {Cube c1,c2; // 创建c1.setinf(1, 2, 3);c2.setinf(2, 3, 4);cout <<"c1表面积:"<< c1.getS() << endl;cout <<"c1体积:"<< c1.getV() << endl;// 成员函数判断string flag = c1.judge(c2) ? "Yes" : "No";cout <<"通过成员函数判断两立方体是否相等:"<< flag << endl;// 全局函数判断string g_flag = g_judge(c1,c2) ? "Yes" : "No";cout << "通过全局函数判断两立方体是否相等:" << flag << endl;system("pause");return 0;}
c1表面积:33
c1体积:6
通过成员函数判断两立方体是否相等:No
通过全局函数判断两立方体是否相等:No
请按任意键继续. . .

练习案例2:点和圆的关系
计算一个圆形类(Circle)和一个点类(Point),计算点和圆的关系

#include <iostream>
using namespace std;
class Circle {
public:int x = 0;int y = 0;int r;void set_inf(int inputx,int inputy,int inputr) {x = inputx;y = inputy;r = inputr;}
};class Point {
public:int P_x = 0;int P_y = 0;void set_inf(int input_P_x, int input_P_y) {P_x = input_P_x;P_y = input_P_y;}
};string judge(Circle c, Point p) {int distance = sqrt((c.x - p.P_x)*(c.x - p.P_x) + (c.y - p.P_y)*(c.y - p.P_y));if (distance == c.r) {return "在圆上";}else if (distance < c.r) {return "在圆内";}else {return "在圆外";}
}
int main() {Circle c1;Point p1;c1.set_inf(1, 1, 1);p1.set_inf(1, 0);string flag = judge(c1, p1);cout << flag << endl;system("pause");return 0;}
在圆上
请按任意键继续. . .

代码比较多,可以分文件编写,分成Circle.cpp,Circle.h,Point.h,Point.cpp,cpp中放函数实现方法,.h中放函数申明

circle.cpp

#include "circle.h"
void Circle::set_inf(int inputx, int inputy, int inputr) {x = inputx;y = inputy;r = inputr;
};

circle.h

#pragma once
#include <iostream>
using namespace std;class Circle {
public:int x = 0;int y = 0;int r;void set_inf(int inputx, int inputy, int inputr);
};

point.cpp

#include "point.h"void Point::set_inf(int input_P_x, int input_P_y) {P_x = input_P_x;P_y = input_P_y;
}

point.h

#pragma once
#include <iostream>
using namespace std;class Point {
public:int P_x = 0;int P_y = 0;void set_inf(int input_P_x, int input_P_y);
};

main.cpp

#include <iostream>
using namespace std;
#include "circle.h"
#include "point.h"
//class Circle {
//public:
//	int x = 0;
//	int y = 0;
//	int r;
//	void set_inf(int inputx,int inputy,int inputr) {
//		x = inputx;
//		y = inputy;
//		r = inputr;
//	}
//};//class Point {
//public:
//	int P_x = 0;
//	int P_y = 0;
//	void set_inf(int input_P_x, int input_P_y) {
//		P_x = input_P_x;
//		P_y = input_P_y;
//	}
//};string judge(Circle c, Point p) {int distance = sqrt((c.x - p.P_x)*(c.x - p.P_x) + (c.y - p.P_y)*(c.y - p.P_y));if (distance == c.r) {return "在圆上";}else if (distance < c.r) {return "在圆内";}else {return "在圆外";}
}
int main() {Circle c1;Point p1;c1.set_inf(1, 1, 1);p1.set_inf(1, 0);string flag = judge(c1, p1);cout << flag << endl;system("pause");return 0;}
在圆上
请按任意键继续. . .

二、对象特性

2.1 对象的初始化和清理

C++面向对象来源于生活,每个对象都会有初始化设置以及对象销毁前的清理数据设置。对象的初始化清理也是两个非常重要的安全问题。

  • 一个对象或者变脸没有初始状态,对其使用后果是未知。
  • 同样,使用完一个对象或变量,没有及时清理,也会造成一定的安全问题。

C++利用构造函数析构函数解决以上问题,两个函数会被编译器自动调用,如果不提供构造和析构,编译器会提供构造函数和析构函数的空实现。

  • 构造函数:创建对象时为对象的成员属性赋值;
  • 析构函数:对象销毁前系统自动调用,执行一些清理工作。

构造函数语法 类名(){}

  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次

析构函数语法~类名(){}

  1. 析构函数,没有返回值也不写void
  2. 函数名称与类名相同,在名称前加上符号~
  3. 析构函数不可以有参数,因此不可以发成重载
  4. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
#include <iostream>
using namespace std;
class Person {
public: // 加上作用域Person() {cout << "构造函数的调用!" << endl;}~Person() {cout << "析构函数的调用!" << endl;}
};void test() {Person p; // 在栈区创建实例化对象
}
int main() {test();system("pause");return 0;
}
构造函数的调用!
析构函数的调用!
请按任意键继续. . .

2.2 构造函数的分类与调用

分类方式:

  1. 按参数分:有参构造和无参构造
  2. 按类型分:普通构造和拷贝构造

调用方式:

  1. 括号法
  2. 显示法
  3. 隐式转化法
#include <iostream>
using namespace std;class Person {// 构造函数// 分类方式:有参构造、无参构造   普通构造和拷贝构造// 无参构造
public:Person() {cout << "调用的为无参构造!" << endl;}// 有参构造Person(int a) {age = a;cout << "调用的为有参构造!" << endl;}// 以上都为普通构造// 拷贝构造Person(const Person &p) {age = p.age;cout << "调用的为拷贝构造!" << endl;}int age;
};int main() {// 调用方式// 1. 括号法// 无参调用Person p1;// 有参调用Person p2(10);// 拷贝调用Person p3(p2);// 2.显示法Person p4 = Person(10);// Person(p4); 不可用拷贝构造 初始化匿名函数Person p5 = Person(p4); // Person(p4)为匿名对象,当前行执行结束后,会立即被析构掉// 隐式转化法Person p6 = 10; //相当于Person p6 = Person(10)system("pause");return 0;
}
调用的为无参构造!
调用的为有参构造!
调用的为拷贝构造!
调用的为有参构造!
调用的为拷贝构造!
调用的为有参构造!
请按任意键继续. . .

拷贝构造函数使用时机

  1. 使用一个已经创建完毕的对象来初始化一个新对象
  2. 值传递的方式给函数参数传值
  3. 值方式返回局部对象
#include <iostream>
using namespace std;
class Person {
public:Person() {cout << "无参构造" << endl;}Person(int a) {age = a;cout << "有参构造" << endl;}Person(const Person &p) {age = p.age;cout << "拷贝构造" << endl;}int age;
};void test() {Person p1(10);Person p2(p1); // 用一个已经创建好的对象来初始化一个新对象cout <<"p1的年龄为:"<< p1.age << endl;cout <<"p2的年龄为:"<< p2.age << endl;}
void test2(Person p) {
}Person test3() {static Person p;return p;
}
//void todo() {
//	test3();
//}
int main() {//Person p(10);Person p = test3();system("pause");return 0;
}
无参构造
拷贝构造
请按任意键继续. . .

值传递的方式给函数参数传值和值方式返回局部对象都相当于将原来的值拷贝了一份,因此相当于把原来的拷贝了一份.

2.3 构造函数调用规则

  • 如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
  • 如果用户定义拷贝构造函数,C++不会再提供其他构造函数

可以这么理解: 拷贝构造>有参构造>无参构造,如果用户提供一个构造,编译器会自动补齐比他更高级的构造,不会提供比他更低级的构造。比如如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造

#include <iostream>
using namespace std;class Person {
public:Person(int a) {m_age = a;}int m_age;
};int main() {//Person p;// 报错Person p(10); // 不报错Person p2(p); // 不报错system("pause");return 0;}

2.4 浅拷贝与深拷贝

  • 浅拷贝:简单的赋值拷贝操作
  • 深拷贝:在堆区重新申请空间,进行拷贝操作
    在这里插入图片描述
#include <iostream>
using namespace std;
class Person {
public:Person() {cout << "无参构造" << endl;}Person(int a,int n) {cout << "有参构造" << endl;age = a;// num = &n;报错num = new int(n);}Person(const Person& p) {cout << "拷贝函数" << endl;age = p.age;//num = p.num; // 报错num = new int (*p.num);}// 析构函数~Person() {cout << "调用析构函数" << endl;// 将指针开辟区域释放if (num != NULL) {delete num;num = NULL;}}int age;int* num;  // 指针在堆区开辟
};
void test() {int num = 123;// 有参构造Person p1(10, num);// 拷贝构造Person p2(p1); // 报错
}
int main() {test();system("pause");return 0;}
有参构造
拷贝函数
调用析构函数
调用析构函数
请按任意键继续. . .

主要原因就是浅拷贝的地址被释放之后,二次释放。深拷贝会重新开辟一个地址,这样就不会再同一个地址释放多次。

2.5 初始化列表

语法:构造函数():属性1(值1),属性2(值2)…{}

#include <iostream>
using namespace std;class Person {
public:Person() {}Person(string n,int a,string ad):name(n),age(a),address(ad){}string name;int age;string address;
};int main() {Person p1("张三", 13, "安徽");cout << "姓名:" <<p1.name<< "   年龄:" << p1.age<<"   住址:" << p1.address<<endl;//Person p2("李四", 12); //报错,少参数//cout << "姓名:" << p2.name << "   年龄:" << p2.age << "   住址:" << p2.address << endl;system("pause");return 0;}
姓名:张三   年龄:13   住址:安徽
请按任意键继续. . .

2.6 类对象作为类成员

#include <iostream>
using namespace std;class Student {
public:string name;int score;Student(string n,int s):name(n),score(s){cout << "Student有参构造" << endl;}~Student() {cout << "Student析构函数" << endl;}};class Teacher {
public:string name;Student stu;Teacher(string t_n,string s_n,int s):name(t_n),stu(s_n,s){}
};void test() {Teacher t1("李老师", "张三", 12);cout << "老师姓名:" << t1.name << "  学生姓名:" << t1.stu.name << "   学生分数:" << t1.stu.score << endl;
}
int main() {test();system("pause");return 0;}
Student有参构造
老师姓名:李老师  学生姓名:张三   学生分数:12
Student析构函数
请按任意键继续. . .

2.7 静态成员

在成员变量和成员函数前加上关键字static,成为静态成员,分为:

  • 静态成员变量

    • 所有对象共享同一份数据
    • 在编译阶段分配内存
    • 类内声明,类外初始化
  • 静态成员函数

    • 所有对象共享同一个函数
    • 静态成员函数只能访问静态成员变量
#include <iostream>
using namespace std;
class Person {
public:string name;static int score; // 静态成员变量,需要类内定义,类外初始化void func() {name = "张三";score = 10;cout << "调用函数func!" << endl;}static void func2() {//name = "李四"; // 报错,静态成员函数只能调用静态成员变量score = 200;cout << "调用函数func2!" << endl;}
};
int Person::score=100;int main() {Person p1;cout <<"p1分数为:"<< p1.score << endl;Person p2;p2.score = 60;cout << "p2分数为" << p2.score << endl;cout << "p1分数为" << p1.score << endl;// 直接使用类名调用静态成员变量cout << "Person::score:" << Person::score << endl;  // 注意不能使用. 而是使用::// 静态成员函数p2.func();p2.func2();system("pause");return 0;}
p1分数为:100
p2分数为60
p1分数为60
Person::score:60
调用函数func!
调用函数func2!
请按任意键继续. . .

三. C++对象模型和this指针

3.1 成员变量和成员函数分开存储

C++中类内成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上

#include <iostream>
using namespace std;
class Person {
public:int a;  // 是类的对象static int b;// 不是类的对象void func() {}static void func2(){}
};
int Person::b = 0;
int main() {Person p;cout << "size of p=" << sizeof(p) << endl;system("pause");return 0;}
size of p=4
请按任意键继续. . .

3.2 this指针概念

c++提供特殊的对象指针——this指针,this指针指向被调用的成员函数所属对象。this指针本质是一个指针常量,指向对象不能发生变化,指向对象的值可以发生变化。

  • this指针时隐含每一个非静态成员函数内的一种指针
  • this指针不需要定义,直接使用即可

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this
#include <iostream>
using namespace std;
class Person {
public:int age;Person(int age) {//age = age; // 编译器认为这两个age是一样的//1. 防止形参和成员变量同名this->age = age; // 将形参age赋值给成员变量age}//2. 返回对象本身// 如果不是引用类型的话,每一次都会创建一个新对象,而不是在原来的对象上进行累加Person& Personadd(Person p) {this->age += p.age;return *this;}
};int main() {Person p(10);Person p1(20);cout << "p年龄:" << p.age << endl;cout << "p1年龄:" << p.age << endl;p1.Personadd(p).Personadd(p); // 加两次cout << "年龄:" << p1.age << endl;system("pause");return 0;}
p年龄:10
p1年龄:10
年龄:40
请按任意键继续. . .

3.3 空指针访问成员函数

空指针可以调用成员函数,但是要注意有没有用到this指针。如果用到了this指针,需要加以判断保证代码的健壮性

#include <iostream>
using namespace std;class Person {
public:int age;void func() {cout << "func的调用" << endl;}void func2() {// 添加判断 增强代码的健壮性if (this == NULL) {return;}cout << "年龄为" << age << endl;  // age相当于this.age 如果是空指针的话会报错}
};int main() {// 创建一个空指针Person* p = NULL;p->func();p->func2(); // 用到this指针会报错system("pause");return 0;}
func的调用
请按任意键继续. . .

3.4 const修饰成员函数

常函数

  • 成员函数后加const后我们称这个函数为常函数
  • 常函数不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中仍然可以修改

常对象

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数
#include <iostream>
#include <iostream>
using namespace std;
class Person{
public:string name; //成员变量mutable int age; // mutable修饰使得常函数也能进行修改// 无参构造函数Person() {}// 定义一个成员函数void test() {cout << "调用test函数" << endl;}// 定义一个常函数void func() const{//name = "李四"; // 报错,不能修改正常的成员属性age = 12; // 不报错,可以修改mutable修饰的成员变量}};int main() {// 创建一个常对象const Person p;//p.test();// 不可以调用正常的成员函数p.func(); // 可以调用常函数cout << "年龄为:" << p.age << endl;system("pause");return 0;}
年龄为:12
请按任意键继续. . .

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

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

相关文章

美易官方:诡异一幕!美国通胀数据超预期上升降息预期却不降反升

美国通胀数据超预期上升&#xff0c;降息预期却不降反升&#xff0c;这一诡异一幕引发了市场对于美联储政策走向的猜测和担忧。在经济全球化的大背景下&#xff0c;美国作为全球最大的经济体&#xff0c;其货币政策对于全球经济具有重要影响。因此&#xff0c;这一诡异一幕不仅…

为什么选择CRM系统时,在线演示很重要?

想要知道一款CRM管理系统是否满足企业的需求&#xff0c;操作是否简单&#xff0c;运行是否流畅&#xff0c;最直观的方式就是远程演示。否则&#xff0c;光凭厂商的销售人员介绍一下产品&#xff0c;企业就盲目下单&#xff0c;最后发现功能不匹配&#xff0c;还要赔钱赔时间重…

销售团队如何实现业绩增长?CRM系统的线索管理功能有什么用?

随着“以客户为中心”观念的逐渐普及&#xff0c;销售团队的客户比过去更复杂&#xff0c;交易周期更久&#xff0c;竞争也更激烈。假如没有明确的销售计划&#xff0c;团队可能陷入混乱&#xff0c;最后导致客户&公司之间的负面结果。在这种情况下&#xff0c;人工智能驱动…

Open CV 图像处理基础:(一)Open CV 在windows环境初始化和 Java 动态库加载方式介绍

Open CV 在windows环境初始化和 Java 动态库加载方式介绍 目录 Open CV 在windows环境初始化和 Java 动态库加载方式介绍OpenCV安装opencv-4.4.0下载安装 加载opencv-4.4.0.jar包jar包引入mavn-init.cmdjar包装载到本地maven仓库pom.xml加载动态库 加载动态库opencv_java440.dl…

基于Python实现身份证信息识别

目录 前言身份证信息识别的背景与意义自动识别身份证的需求 实现环境与工具准备Python编程语言OpenCV图像处理库Tesseract OCR引擎 身份证信息识别算法原理图像预处理步骤(图像裁剪、灰度化 、二值化、去噪)信息提取与解析 Python代码实现通过OCR提取身份证号码代码解析身份证信…

AI分割迁移绘画-neural-style

&#x1f3e1; 个人主页&#xff1a;IT贫道-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;私聊博主加WX好友&#xff0c;获取更多资料哦~ &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. 二值化展示图像代码…

docker、docker-compose 离线安装、shell脚本一键安装、卸载

注&#xff1a;二进制包&#xff0c;与脚本在同级目录 docker 离线安装&#xff1a; 包下载&#xff1a;https://download.docker.com/linux/static/stable/x86_64/ docker_install.sh&#xff1a; #!/bin/bash# 指定 Docker 版本和文件名 DOCKER_VERSION"24.0.7" D…

电位器

一、电位器简介 电位器是一种可调的电子元件。它是由一个电阻体和一个转动或滑动系统组成。当电阻体的两个固定触电之间外加一个电压时&#xff0c;通过转动或滑动系统改变触点在电阻体上的位置&#xff0c;在动触点与固定触点之间便可得到一个与动触点位置成一定关系的电压。…

如何将Redis、Zookeeper、Nacos配置为Windows系统的一个服务

说明&#xff1a;当我们在Windows上开发时&#xff0c;不可避免的会用到一些中间件&#xff0c;如Redis、Zookeeper、Nacos等等&#xff0c;当在项目中使用到本地的这些服务器时&#xff0c;我们需要把本地的服务器启动&#xff0c;会开启下面这样的一个窗口。 Redis服务器&am…

uniapp中uview组件库丰富的CountTo 数字滚动使用方法

目录 #平台差异说明 #基本使用 #设置滚动相关参数 #是否显示小数位 #千分位分隔符 #滚动执行的时机 #API #Props #Methods #Event 该组件一般用于需要滚动数字到某一个值的场景&#xff0c;目标要求是一个递增的值。 注意 如果给组件的父元素设置text-align: cente…

C++力扣题目112,113--路径总和,路径总和II

112路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 是…

以太网交换机——稳定安全,构筑数据之桥

交换机&#xff0c;起源于集线器和网桥等网络通信设备&#xff0c;它在性能和功能上有了很大的发展&#xff0c;因此逐渐成为搭建网络环境的常用的设备。 随着ChatGPT爆发&#xff0c;因为用户量激增而宕机事件频频发生&#xff0c;云计算应用催生超大规模算力需求&#xff0c;…

java通过okhttp方式实现https请求的工具类(绕过证书验证)

目录 一、引入依赖包二、okhttp方式实现的https请求工具类2.1、跳过证书配置类2.2、okhttp方式的 https工具类 三、测试类 一、引入依赖包 引入相关依赖包 <!--okhttp依赖包--> <dependency><groupId>com.squareup.okhttp3</groupId><artifactId>…

Vue、uniApp、微信小程序、Html5等实现数缓存

此文章带你实现前端缓存&#xff0c;利用时间戳封装一个类似于Redis可以添加过期时间的缓存工具 不仅可以实现对缓存数据设置过期时间&#xff0c;还可以自定义是否需要对缓存数据进行加密处理 工具介绍说明 对缓存数据进行非对称加密处理 对必要数据进行缓存&#xff0c;并…

php通用后台开发框架源码

php通用后台开发框架源码 基于ThinkPHPBootstrap的快速后台开发框架。 基于Auth验证的权限管理系统&#xff0c;支持无限级父子级权限继承&#xff0c;父级的管理员可任意 增删改子级管理员及权限设置&#xff0c;支持单管理员多角色&#xff0c;支持管理子级数据或个人数据。 …

Linux学习记录——삼십구 数据链路层协议

文章目录 1、了解数据链路层2、认识以太网3、认识MAC地址4、以太网报文5、局域网通信原理1、基本原理2、数据碰撞3、交换机4、ARP协议5、RARP协议6、局域网中间人 6、DNS&#xff08;简单介绍&#xff09;7、ICMP协议1、报文2、traceroute命令 7、NAT技术1、基本过程2、NAPT3、…

C++力扣题目111--二叉树的最小深度

力扣题目链接(opens new window) 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明: 叶子节点是指没有子节点的节点。 示例: 给定二叉树 [3,9,20,null,null,15,7], 返回它的最小深度 2 思路 看完了这篇104.二…

Java入门IDEA基础语法

1&#xff1a;Java入门 1.1 Java简介 Java是什么&#xff1a; Java是一门非常优秀的计算机语言 语言&#xff1a;人与人交流沟通的表达方式 计算机语言&#xff1a;人与计算机之间进行信息交流沟通的一种特殊语言 Java之父&#xff1a;詹姆斯高斯林&#xff08;James Gosli…

履践致远 载誉前行 | 甄知科技获评多项荣誉资质认定!

砥砺深耕 履践致远 甄知科技不断精进 持续成长 获评多项荣誉资质认定 23年4月 甄知成功入库科技型中小企业名单 2023年4月&#xff0c;上海市科技技术委员会公布2023年第二批入库科技型中小企业名单&#xff0c;依据《科技型中小企业评价办法》等要求&#xff0c;经各级评价工…

孩子用什么样的灯对眼睛没有伤害?分享最合适孩子的护眼台灯

为人父母以后&#xff0c;孩子健康成长一定是摆放在首位的&#xff0c;随着孩子慢慢长大&#xff0c;步入更高的年级&#xff0c;作业课程也在随之增多。不少孩子哪怕夜色已经降临&#xff0c;仍就伏案在桌子上完成没有做完的功课&#xff0c;作为父母的我们不得不担心孩子的视…