C++中会生成一些默认的成员函数,构造函数,析构函数之类。如果显式定义了,编译器就不会重新生成默认函数,比如显式定义了带参的构造函数,无参的就不会生成。为了避免造成混乱,C++11让程序员可以控制是否需要编译器生成函数。
在C++11中,可以在默认函数定义或者声明时加上=default,从而显式的指示编译器生成该函数的默认版本,用=default修饰的函数称为显式缺省函数。
class A
{
public:
A(int a): _a(a)
{}
A() = default;//指定函数生成
// 在类中声明,在类外定义时让编译器生成默认赋值运算符重载
A& operator=(const A& a);
private:
int _a;
};
A& A::operator=(const A& a) = default;
int main()
{
A a1(10);
A a2;
a2 = a1;
return 0;
}
在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对
应函数的默认版本,称=delete修饰的函数为删除函数。
class A
{
public:
A(int a): _a(a)
{}
// 禁止编译器生成默认的拷贝构造函数以及赋值运算符重载
A(const A&) = delete;
A& operator(const A&) = delete;
private:
int _a;
};
四.右值引用
======
C++提出了引用,为了提高程序运行效率,C++11引入了右值引用,右值引用也是别名,但是只能对右值引用。
int Add(int a,int b)
{
return a + b;
}
int main()
{
const int&& ra = 10;
int&& rRet = Add(10,20);
return 0;
}
左值和右值并没有给出严格的区分方式,一般认为:
①可以放在=左边的,②或者能够取地址的称为左值,
①只能放在=右边的,②或者不能取地址的称为右值。
int main()
{
int a = 10;
int b = 20;
a = b;
b = a;//a和b都是左值,左值即可放在=的左侧,也可以放在=的右侧
b + 1 =20;//b+1的结果是一个临时变量,没有具体名称,也不能取地址,因此为右值
}
仅靠上边的概念很难区分是左值还是右值,所以一般认为:
1. 普通类型的变量,因为有名字,可以取地址,都认为是左值。
2. const修饰的常量,不可修改,只读类型的,理论应该按照右值对待,但因为其可以取地址(如果只是const类型常量的定义,编译器不给其开辟空间,如果对该常量取地址时,编译器才为其开辟空间),C++11认为其是左值。
3. 如果表达式的运行结果是一个临时变量或者对象,认为是右值。
4. 如果表达式运行结果或单个变量是一个引用则认为是左值。
引用和右值引用比较
int main()
{
// 普通类型引用只能引用左值,不能引用右值
int a = 10;
int& ra1 = a; // ra为a的别名
//int& ra2 = 10; // 编译失败,因为10是右值
const int& ra3 = 10;
const int& ra4 = a;
return 0;
}
普通引用只能引用左值,不能引用右值,
const引用即可引用左值,也可引用右值。
右值引用只能引用右值。
int main()
{
// 10纯右值,本来只是一个符号,没有具体的空间,
// 右值引用变量r1在定义过程中,编译器产生了一个临时变量,r1实际引用的是临时变量
int&& r1 = 10;
r1 = 100;
int a = 10;
int&& r2 = a; // 编译失败:右值引用不能引用左值
return 0;
}
五.lambda表达式
===========
在C++98中,对一个数据集合中的元素排序,可以使用std::sort。
int main()
{
int array[] = {4,1,8,5,3,7,0,9,2,6};
// 默认按照小于比较,排出来结果是升序
std::sort(array, array+sizeof(array)/sizeof(array[0]));
// 如果需要降序,需要改变元素的比较规则
std::sort(array, array + sizeof(array) / sizeof(array[0]), greater());
return 0;
}
但随着C++语法的发展,人们开始觉得上边的写法太复杂了,因此出了lambda表达式。
lambda语法
lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }
[capture-list] 捕捉列表
(parameters) 参数列表
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。
->returntype:返回值类型。
{statement}:函数体。
int main()
{
// 最简单的lambda表达式, 该lambda表达式没有任何意义
[]{};
// 省略参数列表和返回值类型,返回值类型由编译器推导为int
int a = 3, b = 4;
[=]{return a + 3; };
// 省略了返回值类型,无返回值类型
auto fun1 = [&](int c){b = a + c; };
fun1(10)
cout<<a<<" "<<b<<endl;
// 各部分都很完善的lambda函数
auto fun2 = [=, &b](int c)->int{return b += a+ c; };
cout<<fun2(10)<<endl;
// 复制捕捉x
int x = 10;
auto add_x = [x](int a) mutable { x *= 2; return a + x; };
cout << add_x(10) << endl;
return 0;
}
捕捉列表描述了上下文那些数据可以被lambda使用,以及使用的方式传值还是传引用。
[var]:表示值传递方式捕捉变量var
[=]:表示值传递方式捕获所有父作用域中的变量(包括this)
[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针
函数对象与lambda表达式
函数对象,又称为仿函数。即可以像函数一样使用的对象,就是在类中重载了operator()运算符的类对象。
class Rate
{
public:
Rate(double rate): _rate(rate)
{}
double operator()(double money, int year)
private:
double _rate;
};
int main()
{
// 函数对象
double rate = 0.49;
Rate r1(rate);
r1(10000, 2);
// lamber
auto r2 = [=](double monty, int year)->double{return montyrateyear; };
r2(10000, 2);
return 0;
}
六.线程库
=====
函数名 功能
thread() 构造一个线程对象,没有关联任何线程函数,即没有启动任何线程
thread(fn,args1, args2,…) 构造一个线程对象,并关联线程函数fn,args1,args2,… 为线程函数的参数
get_id() 获取线程id
jionable() 线程是否还在执行,joinable代表的是一个正在执行中的线程。
jion() 该函数调用后会阻塞住线程,当该线程结束后,主线程继续执行
detach() 在创建线程对象后马上调用,用于把被创建线程与线程对象分离 开,分离的线程变为后台线程,创建的线程的"死活"就与主线程无关
线程是操作系统中的一个概念,线程对象可以关联一个线程,用来控制线程以及获取线程的状态。
int main()
{
// 线程函数为函数指针
thread t1(ThreadFunc, 10);
// 线程函数为lambda表达式
thread t2([]{cout << “Thread2” << endl; });
// 线程函数为函数对象
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/60a90f8360d29d06bde8e97df62b1354.jpeg)
最后
小编精心为大家准备了一手资料
以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术
【附】架构书籍
- BAT面试的20道高频数据库问题解析
- Java面试宝典
- Netty实战
- 算法
BATJ面试要点及Java架构师进阶资料
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
最后
小编精心为大家准备了一手资料
[外链图片转存中…(img-14pE5Xor-1713414339381)]
[外链图片转存中…(img-wLObaNa3-1713414339381)]
以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术
【附】架构书籍
- BAT面试的20道高频数据库问题解析
- Java面试宝典
- Netty实战
- 算法
[外链图片转存中…(img-dR5I1WxQ-1713414339382)]
BATJ面试要点及Java架构师进阶资料
[外链图片转存中…(img-Jz5st1NZ-1713414339382)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!