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

C++学习记录——유 类和对象(3)

文章目录

  • 1、赋值运算符重载
    • 1、运算符重载
      • 1、理解
      • 2、运算符重载实例
    • 2、赋值运算符重载
  • 2、日期类的实现
    • 1、加减函数
      • 1、加函数
      • 2、减函数
    • 2、前/后置++--重载
    • 3.两个日期相减
  • 其他
    • 1、流插入
    • 2、流提取


日期类的整体实现代码: https://gitee.com/kongqizyd/start-some-c-codes-for-learning.c/tree/master/%E6%97%A5%E6%9C%9F%E7%B1%BB

关于日期类的讲解会比较长,可以边看完整代码边看分析

1、赋值运算符重载

1、运算符重载

1、理解

继续用日期类做例子。

class Date
{
public:Date(int year = 2023, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};

假设现在要比较两个日期数值大小

int main()
{Date d1(2023, 2, 8);Date d2;return 0;
}

我们自然可以定义一个函数,参数类型就是Date类或者说Date的引用类,用来比较两个变量。但这样有些俗套了,或者说很常见的做法,C++有自定义类型和内置类型,内置类型的比较很简单,而自定义类型的比较需要程序员自己确定如何比较。C++对此有运算符重载函数,用到关键字operator。现在写一个比较相等的函数。

bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}

要把他当做一个正常的函数,并且d1和d2的位置也就是在main调用这个函数时的位置,d1 == d2即可调用。这里先把三个变量变成公有类型才能在外部访问。

d1 == d2;
operator==(d1, d2);

调用时这两种写法都可,不过第一个更简单。第一个对于程序,会及时地转换成operator==(d1, d2)。

但是如果想打印结果,不能用d1 == 2,因为实际写出来时,<< >>运算符优先级高于等于号,所以需要括起来。

现在是把这个函数放到全局里,所以类里的成员变量要换成公有的才行。而另一个办法就是把这个函数放到类里面也可,但如果直接放进去编译器就会告诉你参数放多了,因为本身是有this指针的,所以括号里放一个参数即可。

	bool operator==(const Date& d){return _year == d._year&& _month == d._month&& _day == d._day;}

调用时这样写就行

cout << d1.operator==(d2) << endl;

运算重载特征:
不能通过连接其他符号来创建新的操作符:比如operator@
重载操作符必须有一个类类型参数
用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
.* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出
现。

2、运算符重载实例

写一下小于的函数。

	bool operator<(const Date& d){if (_year < d._year)return true;else if (_year == d._year && _month < d._month)return true;else if (_year == d._year && _month == d._month && _day < d._day)return true;elsereturn false;

当然也可以放到一块,直接就是return一串代码。

cout << d1.operator<(d2) << endl;

这样就可以检验一下结果。

不过我们还有一个更简单地写法。比如写小于等于的函数

	bool operator<=(const Date& d){return *this < d || *this == d;}

大于等于

	bool operator>=(const Date& d){return !(*this < d);}

不能出现*this > d,编译器会报出一堆错。

在这里插入图片描述

2、赋值运算符重载

现在要把d2的值赋值给d1.

	void operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;}

这里不用引用也可以,因为我们写好的拷贝构造函数是一个成熟的函数,用引用传参,而这里传参,调用完拷贝构造就好了,不过用一下引用能省点编译器工作。

但是这样不是赋值的完整函数。在C语言中,我们可以连续赋值,也就是x = y = z,如果按照这样写,一定会出错。这里的实现思路就是z赋值给y后要返回一个值,返回的这个值再赋值给x,这个返回值其实也就是y。

	Date& operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;return *this;}

还有一个问题,有可能会出现自己给自己赋值,所以加个判断。

		if (this != &d){_year = d._year;_month = d._month;_day = d._day;}

如果不写重载,编译器还是会自己生成,规则还是一样,有资源申请才需要自己写。

拷贝构造会这样写:
Date d2 = d1;
Date d2(d1);

重载需要一个Date类型的变量,而拷贝构造可以不需要,所以重载不能这样写,Date d2 = d1。

2、日期类的实现

现在写一个比较全的日期类。

<Date.h>

#pragma once
#include <iostream>
using namespace std;class Date
{
public:Date(int year = 2023, int month = 1, int day = 1);void Print();bool operator==(const Date& d);bool operator!=(const Date& d);bool operator<(const Date& d);bool operator<=(const Date& d);bool operator>=(const Date& d);bool operator>(const Date& d);//Date& operator=(const Date& d);private:int _year;int _month;int _day;
};

<Date.cpp>

#include "Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}bool Date::operator<(const Date& d)
{if (_year < d._year)return true;else if (_year == d._year && _month < d._month)return true;else if (_year == d._year && _month == d._month && _day < d._day)return true;elsereturn false;
}bool Date::operator<=(const Date& d)
{return *this < d || *this == d;
}bool Date::operator>=(const Date& d)
{return !(*this < d);
}bool Date::operator>(const Date& d)
{return !(*this <= d);
}bool Date::operator!=(const Date& d)
{return !(*this == d);
}

<Test.cpp>

#include "Date.h"void Test1()
{Date d1(2023, 2, 8);d1.Print();Date d2(2023, 2, 28);d2.Print();
}int main()
{Test1();return 0;
}

针对初始化日期的函数,有一个现实问题没有想到,就是如果年是负数呢?或者其它数是一个不可能的数呢?所以要加上检查函数,比如上一篇的我GetDay等函数。

int GetMonthDay(int year, int month)
{int monthArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 ,31 };if (month == 2 && year % ((4 == 0 && year % 100 != 0) || (year % 400) == 0)){return 29;}else{return monthArr[month];}
}Date::Date(int year, int month, int day)
{if (month > 0 && month < 13 && (day > 0 && day <= GetMonthDay(year, month))){_year = year;_month = month;_day = day;}elsecout << "日期非法" << endl;
}

1、加减函数

1、加函数

写上相加的函数,这里的思路也和上一篇一样,有了返回值,+=也可以连续+=。如果这样写:Date d2 = d1 += 100,是会把d1也给改变。

Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if(_month == 13){++_year;_month = 1;}}return *this;
}
	Date d2 = d1;d2 += 100;d2.Print();d1.Print();

再写上+。

Date Date::operator+(int day)
{Date tmp(*this);tmp._day += day;while (tmp._day > GetMonthDay(tmp._year, tmp._month)){tmp._day -= GetMonthDay(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){++_year;tmp._month = 1;}}return tmp;
}
	Date d3 = d1 + 100;d3.Print();d1.Print();

用临时变量tmp,防止d1被改变。

出了作用域,*this存在,所以可以用引用,而tmp不存在,不能用引用。也可以在tmp前加上static,也不能用引用,d1为最一开始的数据,d2 = d1 + 100,没有问题,但是同样的,静态区里的这个tmp没有清除,它会接着上一次数据继续加,所以后面再来个d3 = d1 + 100就不是正确数据了。静态变量只会初始化一次,所以再次调用就不会被初始化。

+=和+的代码有些像,我们简化一下

Date Date::operator+(int day)
{Date tmp(*this);tmp += day;/*tmp._day += day;while (tmp._day > GetMonthDay(tmp._year, tmp._month)){tmp._day -= GetMonthDay(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){++_year;tmp._month = 1;}}*/return tmp;
}

+里面用+=。+=也可以使用+。

*this = *this + day;

不过实现+=,+里面放+=更好。因为+本身有拷贝,*this = *this + day还会有赋值。

2、减函数

减去天数,我们要往前倒月,倒年,先把年或者月给减好,然后再去获取天数。

Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date::operator-(int day)
{Date tmp(*this);tmp -= day;
}

加减函数齐全后,有些问题就可以解决。d2 += -100,如果还是之前的代码,那么最终的结果不切实际,转换一下就是d2 -= 100,所以在每个函数开头,我们还需要加上判断。

Date& Date::operator+=(int day)
{//*this = *this + day;if (day < 0){*this -= -day;return *this;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if(_month == 13){++_year;_month = 1;}}return *this;
}

另外三个也是如此。

2、前/后置+±-重载

前置++比较简单,可以用引用,传入数据后+1,然后返回即可。

Date& Date::operator++()
{*this += 1;return *this;
}

后置++需要注意些,我们要返回一个+1之前的值,所以需要调用拷贝构造,创建一个临时变量。

Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}

至于编译器如何辨别是前还是后,这自有办法,不过为了构成重载,声明的时候后置会在括号里写上int,不必写变量名,仅供编译器区分用。实际比较起来,前置++还是更简单,不需要调用其他,一般情况下前置++用得比较多。

	Date& operator++();//前置++Date operator++(int);//后置++,int只是为了占位,和前置函数构成重载
void Test2()
{Date d1(2023, 2, 8);d1.Print();++d1;//前置正常++d1++;//后置会传一个形参类型的参数
}

–是这样写

Date& Date::operator--()
{*this -= 1;return *this;
}Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}

测试的时候可以显式调用

d1.operator++(0);

3.两个日期相减

用int类型的减函数。

声明:int operator-(const Date& d);

int Date::operator-(const Date& d)
{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++min;++n;}return n * flag;
}

测试代码

void Test5()
{Date d1(2023, 2, 8);d1.Print();Date d2(2002, 8, 4);d2.Print();cout << d1 - d2 << endl;
}

其他

1、流插入

像上面的Print函数,可不可cout打印呢?Print函数里是用cout实现的,那么可不可以直接cout << d1?实际上不行,但如果后面跟的是一个内置类型的变量,cout就可以了。C++有osream这个类,类里有cout等成员函数,但和默认成员函数不同,它们即使不写也有默认的函数,而其他成员函数就必须要写,ostream类已经写好了常用变量类型的函数重载,并且也写了<<的运算符重载,所以我们在用cout打印时不需要担心类型,因为C++已经写好了。

那么我们想用cout打印自定义类型的数据,那就需要自己写,写到自己的类里。

void Date::operator<<(ostream& out)
{out << _year << "年" << _month << "月" << _day << "日" << endl;
}

这样写出来,括号还是有两个参数,但是第一个参数是默认的*this,也就是外部声明的d1这些变量。运算符重载写的时候,要按照参数顺序写,所以最后就是d1 << cout。这样有些奇怪,不是我们平常见到的那样,那么把他从类里拿出来写就可以控制顺序了,但这样就会有一个问题,成员变量无法访问,除去把他们变公有外,还可以添加友元函数。

声明:void operator<<(ostream& out, const Date& d);

类里这样写

	//友元friend void operator<<(ostream& out, const Date& d);

定义:

void operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}

测试代码

	operator<<(cout, d1);cout << d1;

平常写流插入的时候很多都是连续写,所以还需要改进,要有返回值。

ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}

2、流提取

流提取的参数不能加const,加const的作用是为了减少拷贝。

声明: istream& operator>>(istream& in, Date& d);
friend istream& operator>>(istream& in, Date& d);

定义

istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

测试代码

void Test7()
{Date d1;cin >> d1;cout << d1;
}

为了更简洁,我们可以用内联函数。实际上在类里面定义的成员函数,就默认为内联函数。那么Date.cpp文件里可以不写,把定义放到.h文件里,前面加上inline

inline ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}inline istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

本篇最一开始给的链接可以看到全部的代码,里面出现的const可以暂且不管,下一篇会写出为什么加const。

结束。

相关文章:

C++学习记录——유 类和对象(3)

文章目录1、赋值运算符重载1、运算符重载1、理解2、运算符重载实例2、赋值运算符重载2、日期类的实现1、加减函数1、加函数2、减函数2、前/后置--重载3.两个日期相减其他1、流插入2、流提取日期类的整体实现代码: https://gitee.com/kongqizyd/start-some-c-codes-for-learning…...

基于Hi3861平台的OpenHarmony程序是如何启动运行的

一、前言 在继续后面课程的内容讲解前&#xff0c;我们要知道在H3861平台上编写的代码到底是如何启动的&#xff0c;这一点很重要。 先分析HelloWorld程序的启动运行流程&#xff0c;并顺便讲解OpenHarmony在H3861平台的&#xff0c;系统是从哪里启动的。 反着推导函数之间具体…...

2023彻底解决Typora使用iPic微博图床失效问题

一、问题描述用Typora搭配iPic图床使用&#xff0c;最近csdn图片显示不出来用浏览器打开图片显示403&#xff0c;这里原因是微博图床出问题了导致的而使用iPic其他图床则需要一直付费&#xff0c;那有没有一劳永逸的解决所有问题呢&#xff1f;二、旧图恢复首先怎么找回旧图&am…...

Revit中添加水平仰视平面图及水平剖面

一、 Revit中如何添加水平仰视平面图 在Revit平面视图中视角是俯视视角&#xff0c;但是在一些特殊的情况下&#xff0c;我们可能需要创建仰视视角的平面视图&#xff0c;例如我们需要向上看天花板的灯具布置的时候。 1.下面讲一下如何在添加仰视平面视图的方法。如图1在模型中…...

Python 循环语句

Python的循环语句&#xff0c;程序在一般情况下是按顺序执行的。编程语言提供了各种控制结构&#xff0c;允许更复杂的执行路径。循环语句允许我们执行一个语句或语句组多次&#xff0c;下面是在大多数编程语言中的循环语句的一般形式&#xff1a;Python 提供了 for 循环和 whi…...

使用 ThreeJS 实现第一个三维场景(详)

文章目录参考描述index.html三维场景的基本实现导入 ThreeJS准备工作场景摄像机视锥体正交摄像机透视摄像机渲染器后续处理将摄像机添加至场景中移动摄像机设置画布尺寸将渲染器创建的画布添加到 HTML 元素中渲染物体结构材质合成将物体添加至场景中代码总汇执行效果动画reques…...

《小猫猫大课堂》三轮5——动态内存管理(通讯录动态内存化)

宝子&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重…...

【Selenium学习】Selenium 八大定位法

1.1 ID定位HTML Tag 的 id 属性值是唯一的&#xff0c;故不存在根据 id 定位多个元素的情况。下面以在百度首页搜索框输入文本“python”为例。搜索框的 id 属性值为“kw”&#xff0c;如图1.1所示&#xff1a;代码如下&#xff0c;“find_element_by_id”方法已废弃&#xff0…...

算法训练营 day41 贪心算法 单调递增的数字 买卖股票的最佳时机含手续费

算法训练营 day41 单调递增的数字 买卖股票的最佳时机含手续费 单调递增的数字 738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09; 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c…...

【数据结构-JAVA】排序

排序在现实生活中的应用可谓相当广泛&#xff0c;比如电商平台中&#xff0c;选购商品时&#xff0c;使用价格排序或是综合排序、高考填报志愿的时候&#xff0c;会参考全国大学排名的情况。下面介绍一些计算机中与排序相关的概念&#xff1a;排序&#xff1a;所谓排序&#xf…...

基于注解管理Bean

一、介绍从 Java 5 开始&#xff0c;Java 增加了对注解&#xff08;Annotation&#xff09;的支持&#xff0c;它是代码中的一种特殊标记&#xff0c;可以在编译、类加载和运行时被读取&#xff0c;执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下&#x…...

Containerd 的 Bug 导致容器被重建!如何避免?

作者简介邓宇星&#xff0c;SUSE Rancher 中国区软件架构师&#xff0c;6 年云原生领域经验&#xff0c;参与Rancher 1.x 到 Rancher 2.x 版本迭代&#xff0c;目前负责 Rancher For openEuler(RFO) 项目开发。最近我们关注到一个关于 containerd 运行时的 issue(​​https://g…...

win环境安装部署Jenkins

win环境安装部署Jenkins&#xff0c;2022年11月&#xff1a;从2022年 6 月 28 日发布的 Jenkins 2.357 和2022年9 月发布的 LTS 版本开始&#xff0c;Jenkins 需要 Java 11 才能使用&#xff0c;放弃 Java 8&#xff0c;如果用JDK1.8&#xff0c;那么Jenkins版本需要是2.357版本…...

网络变压器与不同芯片之间的匹配原则及POE通讯产品需要注意哪些方面

Hqst盈盛电子导读&#xff1a;网络变压器与不同芯片之间的匹配原则及POE通讯产品需要注意哪些方面网络变压器与不同芯片之间的匹配原则&#xff1a;一&#xff0c;电流型PHY芯片一般要配的网络变压器&#xff1a;1、变压器PHY侧3线共模电感 &#xff08;更适合POE产品&#xff…...

Spring WebFlux

目录 基于注解编程模型 函数式编程模型 传统的基于Servlet的Web框架,如Spring MVC,在本质上都是阻塞和多线程的,每个连接都会使用一个线程。在请求处理的时候,会在线程池中拉取一个工作者( worker )线程来对请求进行处理。同时,请求线程是阻塞的,直到工作者线程提示它已…...

C++基础面试题:new和malloc的区别

面试题&#xff1a;new和malloc的区别或new和malloc的异同 相同点&#xff1a; 1、new/delete和malloc/free它们都是内存申请和释放的函数。 2、new/delete和malloc/free 都要一一对应&#xff0c;调用了多少次new 就需要调用多少次delete&#xff1b;同 理调用多少次ma…...

WebDAV之葫芦儿·派盘+KMPlayer

KMPlayer 支持WebDAV方式连接葫芦儿派盘。 KMPlayer几乎可以播放您系统上所有的影音文件,支持几乎全部音视频格式。通过其强大的插件功能,可以支持层出不穷的新格式。软件还具有齐全的操控功能,支持捕获音频、捕获AVI、捕获画面、外挂字幕、自定义编辑设置,是视频爱好者的不…...

杨浦区人工智能及大数据(云计算)企业登记工作(2023年度)的通知

各相关单位&#xff1a; 根据《“长阳秀带”在线新经济产业集聚发展若干政策》&#xff08;杨府发〔2022〕2号&#xff09;及其实施细则的要求&#xff0c;现组织开展2023年度杨浦区人工智能与大数据(云计算&#xff09;企业登记备案工作,现将相关工作通知如下&#xff1a; 一…...

2023年去培训机构学前端还是Java?

选择专业肯定是优先考虑更有发展前景和钱途的专业。毕竟IT专业的培训费都不低&#xff0c;基本都要一两万左右&#xff0c;咱们花钱总是希望获得最大回报。 那么到底哪个更有发展前景呢&#xff1f; 零基础能学得会吗&#xff1f; 就业薪资如何呢&#xff1f; 前言 不知道大家有…...

【React】组件事件

React(二) 创建组件 函数组件 函数组件&#xff1a;使用JS的函数或者箭头函数创建的组件 使用 JS 的函数(或箭头函数)创建的组件&#xff0c;叫做函数组件约定1&#xff1a;函数名称必须以大写字母开头&#xff0c;React 据此区分组件和普通的 HTML约定2&#xff1a;函数组…...

黑/白盒测试说明

白盒测试白盒测试也称结构测试或逻辑驱动测试&#xff0c;它是按照程序内部的结构测试程序&#xff0c;通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行&#xff0c;检验程序中的每条通路是否都能按预定要求正确工作。白盒测试的测试方法有代码检查法、静态结…...

车道线检测-Eigenlanes 论文学习笔记

论文&#xff1a;《Eigenlanes: Data-Driven Lane Descriptors for Structurally Diverse Lanes》 代码&#xff1a;https://github.com/dongkwonjin/Eigenlanes 核心&#xff1a;在 Eigenlane Space 中检测车道线 创新点 Eigenlane&#xff1a;数据驱动的车道描述符&#xff…...

docker run mysql -e 的环境变量 Environment Variables

例子 sudo docker run -itd --name DockerMysqlLatest3307 -p 3307:3306 -e MYSQL_ROOT_PASSWORDroot的密码 mysql:latest### root无密码 sudo docker run -itd --name Mysql57 -p 57:3306 -e MYSQL_ALLOW_EMPTY_PASSWORDroot mysql:5.7https://hub.docker.com/_/mysql?tabde…...

第17章 MongoDB 条件操作符教程

第17章 MongoDB 条件操作符教程 描述 条件操作符用于比较两个表达式并从mongoDB集合中获取数据。 在本章节中&#xff0c;咱们将讨论如何在MongoDB中使用条件操作符。 MongoDB中条件操作符有&#xff1a; (>) 大于 - $gt(<) 小于 - $lt(>) 大于等于 - $gte(< …...

电子技术——共源共栅放大器

电子技术——共源共栅放大器 之前我们提到过&#xff0c;提高基础增益单元&#xff08;共源放大器&#xff09;的一种方法是提高其 ror_oro​ 的阻值&#xff0c;之后我们学过共栅放大器作为电流缓冲器可以做到这一点&#xff0c;自然地我们就得到了终极解决方案&#xff0c;也…...

《MySQL学习》 事务隔离 与 MVCC

《MySQL学习》 事务隔离 一.事务的概念 事务保证一组数据要么全部成功要么全部失败&#xff0c;MySQL的事务基于引擎&#xff08;如InnoDB&#xff09;实现。 二.事务的隔离性与隔离级别 MySQL的标准隔离级别&#xff1a; 读未提交 &#xff1a; 一个事务还没提交时&#…...

html(二)基础标签

一 HTML中的注释 重点&#xff1a; 在哪写注释? 注释的形式? vs code和webstorm都可以通过 ctrl / 进行单行注释和取消注释 ① html中注释的形式 1) html文档中单行和多行注释是"<!-- -->" -->html2) 在html文档中,script标签…...

leetcode刷题---递归思想

leetcode刷题---递归思想&#xff09;1.1 递归介绍1.2 基本步骤1.3 代表题目1.3.1 入门题---青蛙跳1.3.2.1 初级题226.翻转二叉树112.路径总和1.3.3 中级题---汉诺塔问题1.3.4 进阶题---细胞分裂1.1 递归介绍 如果在函数中存在着调用函数本身的情况&#xff0c;这种现象就叫递…...

ThreadLocal 源码级别详解

ThreadLocal简介 稍微翻译一下&#xff1a; ThreadLocal提供线程局部变量。这些变量与正常的变量不同&#xff0c;因为每一个线程在访问ThreadLocal实例的时候&#xff08;通过其get或set方法&#xff09;都有自己的、独立初始化的变量副本。ThreadLocal实例通常是类中的私有静…...

训练营day17

110.平衡二叉树 力扣题目链接 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 返回 true 。 示…...

微信怎么做一些微网站/没经验怎么开广告公司

因为项目的需求&#xff0c;需要对应国际化语言&#xff0c;所以使用native2ascii命令来转换。 环境&#xff1a;Mac OSJDK版本&#xff1a;1.8工具&#xff1a;iTerm native2ascii简介 用来将别的文本类文件&#xff08;比如*.txt,.ini,.properties,*.java等等&#xff09;…...

phpcms仿行业网站/全网推广公司

一、volatile的定义 Java编程语言允许线程访问共享变量&#xff0c;为了确保共享变量能被准确和一致地更新&#xff0c;线程应该确保通过排他锁单独获得这个变量。Java语言 提供了volatile&#xff0c;在某些情况下比锁要更加方便。如果一个字段被声明成volatile&#xff0c;Ja…...

表白视频制作网站/长沙百度快速排名优化

简介 这节课NeHe课程主要向我们展示了将物理运动规律引入到三维场景中&#xff0c;模拟真实物体的位置变化过程。这节课分别模拟了如下几种运动方式&#xff1a; &#xff08;1&#xff09;在重力作用下的抛物线运动&#xff1b; &#xff08;2&#xff09;匀速运动 &#xff…...

骗子会利用钓鱼网站做啥/本地推广最有效的方法

第五章 系统调用 一、与内核通信 系统调用在用户控件进程和硬件设备之间添加了一个中间层&#xff0c;作用如下“ 为用户空间提供了一种硬件的抽象接口系统调用保证了系统的稳定和安全每个进程都运行在虚拟系统中&#xff0c;而在用户控件和系统的其余部分提供这样一层公共接口…...

天津做网站优化的公司/企业网站优化解决方案

mutation_data_tidy mutation_data_tidy PeRl 这次偶然课题需要用到突变相关数据&#xff0c;在这做一下简单的总结&#xff0c;抛砖引玉。 癌症相关数据最近都是从FIREHOSE上下载的&#xff0c;第一次发现突变数据并不是按照矩阵形式存储的&#xff0c;还需要自己整理清洗数据…...

大型信息类PC网站适合vue做吗/此网站不支持下载视频怎么办

2、解压缩tar -zxvf ffmpeg-2.0.1.tar.gz3、配置,生成Makefile./configure --enable-shared --disable-yasm--prefix/usr/local/ffmpeg如果执行结果不对&#xff0c;可以根据提示信息&#xff0c;并查看帮助&#xff0c;解决问题./configure--help4、编译安装makemake install5…...