《C++标准库第2版》3.1 C++11语言新特性 笔记

3.1 C++11 语言新特性

3.1.1 微小但是重要的语法提升

1.template 表达式内的空格

​ 在两个template表达式的闭符之间放一个空格已经过时,目前两个版本的C++11以后两个版本都支持

vector<list<int> >; // 这是以前的版本
vector<list<int>>;  //这是C++11以后可以书写的版本

2.nullptr 和std::nullptr_t

​ C++11允许使用nullptr取代0或NULL来给指针赋值。

​ nullptr是个新的关键字,自动被转换成各种pointer类型,但不会被转换为任何整数类型。

​ std::nullptr_t被视为一个基础类型

3.1.2 以auto完成类型的自动推导

​ C++11允许你声明一个变量或对象而不需指明自类型,只需要说它是auto。但是需要一个初始化操作。(其类型是根据其初值自动推导出来的)

    auto i = 333;auto ii = 333.33;auto iii = new MyClass();auto iiii = std::make_shared<MyClass>();// 原本使用这个格式定义的//std::shared_ptr<MyClass> iiii = std::make_shared<MyClass>();auto iiiii; //declaration of 'auto iiiii' has no initializer

3.1.3 一致性初始化与初值列

一致性初始化:

​ 面对任何初始化动作,都可以使用相同的语法,也就是大括号;

初值列:

​ 会强迫造成所谓value initialization,意思是即使某个local变量属于某种基础类型,也会被初始化为0(或nullptr,如果它是个指针)

窄化:

​ 精度降低或者数值变动,对大括号而言是不可成立的。(使用大括号赋值,如果精度或者数值变动,就会报错)

用户自定义初值列

​ C++11提供了class template std::initializer_list<>,用来支持一系列值进行初始化,或者“你想要处理一系列值”的任何地方进行初始化。

#include <iostream>
#include <memory>
#include <vector>
#include <string>
class MyClass
{
public:MyClass(int a, int b) { std::cout << "2 args" << std::endl; }MyClass(std::initializer_list<int> values) { std::cout << "std::initialization_list<int>" << std::endl; }~MyClass() = default;
};void functionsList(std::initializer_list<int> values)
{std::cout << "functionsList" <<std::endl;
}int main(int argc, char const *argv[])
{// 都是用大括号完成初始化int values[]{2, 3, 4, 5};std::vector<int> v{2, 4, 6, 8, 100};std::vector<std::string> vs{"hello", "world"};// 初值列会强迫造成value initializationint i;    // 随机值int j{};  // 初值为0int *p;   // 随机值int *q{}; // 初始化为nullptr// 精度或者数值变化,会导致大括号赋值方式报错int x1(5.3);  // 使用括号赋值,没问题int x2 = 5.3; // 使用等号赋值,也没问题//int x3{5.3};  // 报错:narrowing conversion of '5.2999999999999998e+0' from 'double' to 'int' inside { }// 可以使用 class template std::initializer_list<>来支持初始化列。MyClass m{1,2,3,4,5,6};functionsList({12,3213,12341,234,12,34,1});// 如果实参数量正好与构造函数的形参数量一致,只要是使用了大括号,也不会调用“指明实参数量”的构造函数MyClass mm(1,23);MyClass mmm {1,2,3,4,5,6,};MyClass mmmm {1,2};  // 实参数量,刚好满足MyClass(int a, int b),但是还是调用初值列的版本。如果没有初值列版本,数量符合就调用指定实参数量的版本,不会报错。return 0;
}

由于初值列的关系,explicit 对于"接受一个以上实参"的构造函数也变得关系重大。即便是使用=语法,“多数值自动类型转换”也不再起作用

同样的explicit构造函数如果接受的是个初值列,会失去“初值列带有0个、1个或多个初值”的隐式转换能力。

#include <iostream>
class MyClass
{
public:MyClass(int a, int b) { std::cout << "2 args" << std::endl; }explicit MyClass(int a, int b, int c) { std::cout << "explicit 3 args." << std::endl; }~MyClass() = default;
};void fp(const MyClass &cmc)
{std::cout << "hello fp" << std::endl;
}int main(int argc, char const *argv[])
{// 常规使用括号赋值MyClass mc1(1, 2);MyClass mc2(1, 2, 3);// 使用初始化列MyClass mc3{1, 2};MyClass mc4{12, 3, 4};// 使用初始化列和等号MyClass mc5 = {1, 2};// MyClass mc6 = {1,2,3}; // 报错: converting to 'MyClass' from initializer list would use explicit constructor 'MyClass::MyClass(int, int, int)'fp({47, 11});// fp({11,11,12}); // converting to 'const MyClass' from initializer list would use explicit constructor 'MyClass::MyClass(int, int, int)'fp(MyClass{12, 123});fp(MyClass{12, 123, 123});
}

3.1.4 Range-Based for循环

基本格式;

for (decl:coll)
{statement
}

对于decl 有传值、传const引用,传引用

传值:for循环的语句会作用域元素的一份local copy身上。在每一次循环都会调用每个元素的copy构造函数和析构函数。

传const引用:避免每次循环调用每个元素的copy构造函数和析构函数,同时也避免在语句中修改元素的值

传引用:在希望修改元素的值的情况下使用这个。

注意事项:

coll提供成员函数begin()和end()

在for循环中被初始化为decl,不得有任何显式类型转换

#include <iostream>
#include <vector>
#include <string>
class C
{
public:explicit C(const std::string& s) {}~C() = default;
};int main(int argc, char const *argv[])
{std::vector<int> vis{1, 23, 4, 5, 5, 123, 123};for (auto vi : vis){std::cout << "vi = " << vi << std::endl;}for (const auto &cfvi : vis){std::cout << "cfvi = " << cfvi << std::endl;}for (auto &fvi : vis){std::cout << "fvi = " << fvi << std::endl;}// 这个会报错:invalid initialization of reference of type 'const C&' from expression of type 'std::__cxx11::basic_string<char>'// std::vector<std::string> vss{"hello", "world"};// for (const C &elem : vss)// {//     ;// }
}

3.1.5 Move语义和Rvalue Reference

C++11的一个重要的特性就是,支持move semantic(搬迁语义)。避免了非必要拷贝和临时对象

程序员必须自行指明“move是可行的,除非被安插的那个临时对象还会被使用”

C++标准库的class保证了,再一次move之后,对象处于有效但不确定的状态。也就是说,可以在move之后对它赋予新值。

#include <iostream>
#include <string>
#include <utility>int main(int argc, char const *argv[])
{std::string xxx{"asdasdassd"};std::cout << "xxx = "<< xxx <<std::endl;std::string xxx1(std::move(xxx));std::cout << "xxx = "<< xxx <<std::endl;std::cout << "xxx1 = " <<  xxx1 << std::endl;return 0;
}// xxx = asdasdassd
// xxx =
// xxx1 = asdasdassd
# 可以明显看到xxx在使用了move以后,内容被移走了(被偷后只剩个空壳子)

nontrivial class: 如果一个类的构造函数不是编译器自动生成的那么他就是nontrivial class。主要释义在下本的看的书《STL源码剖析》中。

Rvalue和Lvalue Reference的重载规则(用一段代码体现):

#include <iostream>
#include <string>
#include <utility>// 只实现void foo(x&),只能左值调用
void foo(std::string &test)
{std::cout << "foo(std::string &)" << std::endl;
}// 只实现void foo1(const x&)
void foo1(const std::string &test)
{std::cout << "foo1(const std::string &)1" << std::endl;
}// 实现foo2(x&)/foo2(x&&)
void foo2(std::string &test)
{std::cout << "foo2(std::string &)" << std::endl;
}void foo2(std::string &&test)
{std::cout << "foo2(std::string &&)" << std::endl;
}// 实现foo3(x&&)
void foo3(std::string &&test)
{std::cout << "foo3(std::string &&)" << std::endl;
}int main(int argc, char const *argv[])
{std::string xxx{"asdasdassd"};// foo只能左值调用,不能右值调用,会报错foo(xxx);// foo(std::move(xxx));// foo1可以左值,也可以右值foo1(xxx);foo1(std::move(xxx));xxx = std::string("hello");// foo2可以区分左右值调用,调用不同的函数foo2(xxx);foo2(std::move(xxx));xxx = std::string("hello");// foo3只能右值调用,左值会报错// foo3(xxx);foo3(std::move(xxx));return 0;
}// 输出:
// foo(std::string &)
// foo1(const std::string &)1
// foo1(const std::string &)1
// foo2(std::string &)
// foo2(std::string &&)
// foo3(std::string &&)

前面都是说做参数,如果Rvalue reference作为返回值呢?

很明确:你不需要也不应该move()返回值。

3.1.7 关键字noexcept

C++11提供了关键字noexcept,用来指明某个函数无法----或不打算抛出异常

​ 若异常没有在内部处理,一旦异常抛出,程序会终止,然后std::terminate()被调用并默认调用std::abort()

可以指明在某些条件下不抛出异常

#include <iostream>
#include <string>// 因为声明了不抛出异常,一旦抛出异常,程序直接挂掉。这个抛出的异常外面无法捕获。
void foo(int x, int y) noexcept
{throw 1;
}// 可以带一个“常量表达式”作为参数
void foo1(int a, int b) noexcept(false)
{throw 2;
}// 这个里面抛出的异常是可以被捕获的。
void foo2(int a, int b)
{throw 3;
}int main()
{try{foo1(13, 12);// foo(123,12);// foo2(123,123);}catch (int e){std::cout << "error:" << e << '\n';}
}

3.1.8 关键字constexpr

自C++11起,constexpr 可用来让表达式核定于编译期。

以下内容源自微软的官方文档(路径就不贴了)

constexpr由C++11引入,完善于C++14

基本格式:

constexpr literal-typeidentifier=constant-expression;
constexpr literal-typeidentifier{constant-expression};
constexpr literal-typeidentifier(params);
constexpr ctor(params);
class MyConstexprClass
{
public:constexpr MyConstexprClass(int ina, int inb) : a(ina), b(inb) {}~MyConstexprClass() = default;private:int a;int b;
};class MyClass
{
public:MyClass(){}~MyClass() = default;private:int a;int b;
};
// 由于不同的编译器可能表现不一样,还有就是C++标准不一样constexpr的限定也不一样。所以有关constexpr函数和class就不介绍了
int main(int argc, char *argv[])
{constexpr int a = 11;constexpr float b = 1.1;constexpr char c = 2;constexpr double d = 23.324;// 这个报错:uninitialized//constexpr double d1;// 报错 string 不是一个文本类型// constexpr std::string str("132132465465");constexpr MyConstexprClass aaa(11, 12);constexpr MyConstexprClass aaa1 = aaa;constexpr MyClass  cmc();  //这样不会报错// 这样报错 has no 'constexpr' constructor(部分报错内容)// constexpr MyClass cmc2 = cmc;return 0;
}

3.1.9 崭新的Template特性

1.从C++11起,template可以有“得以接受个数不定之template实参”的参数。

#include <iostream>void print()
{std::cout << " no para" << std::endl;
}template <typename T>
void print(const T &content)
{std::cout << content << " one para" << std::endl;
}template <typename T, typename... Type>
void print(const T &first, const Type &...args)
{std::cout << first << std::endl;print(args...);
}int main(int argc, const char **argv)
{print(123, 12.34, "hello", "world");return 0;
}// 输出
//  123
//  12.34
//  hello
//  world
//   no para// 加上一个参数的template print后
// 123
// 12.34
// hello
// world one para

2.从C++11起,支持template type definition.使用关键字using(给template定义的内容起个别名,在使用时就方便了)

template <typename T>
using Vec = std::vector<T>; 
Vec<int> coll;

3.从C++11起,function tempalte可拥有默认template实参。 local可被当作template实参

3.1.10 Lambda

//完整的lambda应该长这样
auto l = [capture] (param) mutable thorwSpec ->retType {}
// 当你不想访问外部的任何数据的时候capture可以没有
// 括号是可以省略的,但是param mutable throwSpec retType 只要出现任意一个,那么括号就必须有
// param是可以省略的
// mutable 是可以省略的
// throwSpec 是可以省略的
// ->是可以省略的,这个是新式返回值声明形式,和retType绑定出现
// retType是可以省略的//简化版
auto l = []{}

注意事项:

lambda不可以是template.你始终必须指明所有类型

每个lambda表达式的类型都是独一无二的。

capture :捕获方式(其实类似参数传递方式,可以是byvalue/byreference。但是这个是表明访问lambda外部nonstatic对象的方式)

#include <iostream>int main(int argc, char const *argv[])
{int a = 1, b = 2, c = 3;// byvalueauto labv = [=]{std::cout << a + b + c << std::endl;//a++; //无法修改捕获对象的值}; //这个分号别忘了。(忘了也没事,反正编译不过)// by referenceauto larf = [&]{a++;b++;c++;};// 还可以分别指定每一个参数的方式,但是这样就必须指明被捕获的对象的名称,直接写名称就代表byvalue.auto larl = [a, &b, c]{std::cout << a << b << c << std::endl;b++;};// 可以先指定一个默认的捕获方式,然后再指明某个对象的特殊的捕获方式auto larl1 = [=,&c]{std::cout << a << b << c << std::endl;c++;};//这样不会报错,但是有警告,还是别这样写了。看起来就很别扭// auto larl2 =  [=,c]  // {//     std::cout << a << b << c << std::endl;// };// auto larl3 = [&,&c]{//     std::cout << a << b << c << std::endl;// };// 如果想在lambda内修改捕获的对象,但是呢又不想影响对象外面的值那么就添加mutableauto lam = [=]() mutable{a++;b++;c++;std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl;};// 调用方式labv();                                                                // 6std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl; // a = 1,b = 2,c = 3larf();std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl; // a = 2,b = 3,c = 4larl();                                                                // 133, 这里有个疑问a/c不是在上一步改成了2/4了么?std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl; // a = 2,b = 4,c = 4larl1();                                                               // 124std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl; // a = 2,b = 4,c = 5lam();                                                                 // a = 2,b = 3,c = 4std::cout << "a = " << a << ",b = " << b << ",c = " << c << std::endl; // a = 2,b = 4,c = 5return 0;
}
// 补充知识点:
// 使用值传递时,编译器将lambda中的捕获的变量值初始化为main函数中的同名变量的值,之后,lambda中的捕获变量与main函数中的同名变量不再有任何关系。
// 使用引用传递时则不同,lambda中的捕获变量为main函数中同名变量的副本,两者在内存中的地址是相同的。

3.1.11 关键字decltype

使用方式:decltype(expression)

作用:让编译器找出expression的类型。

使用场景:

​ 声明返回类型

​ 在超编程中

​ 传递lambda的类型

3.1.12 新的函数声明语法

C++11以后,可以将一个函数的返回类型声明于参数列之后。

#include <iostream>
// 新的函数声明语法// 出现在声明中,不行。
// func1(int x,int y)->int; int func1(int x, int y)
{return x+y;
}// 出现在定义中,这样也不行,编译报错
// 'func2' function with trailing return type not declared with 'auto' type specifier
// func2(int x)->int
// {
//     return x;
// }// 查了资料后,编译通过,普通已知返回类型的函数,这样写感觉意义不大,感觉只需要知道有这么个写法就行
auto func(int x, int y) ->int;  //
auto func(int x, int y)->int
{return x+y;
}// 看看书上的例子,用的是function template, 个人感觉:用在返回类型未知的地方比较合理。
template <typename T1, typename T2>
auto add(T1 x, T2 y) ->decltype(x+y);template <typename T1, typename T2>
auto add(T1 x, T2 y) ->decltype(x+y)
{return x + y;
}int main(int argc, const char **argv)
{std::cout << add(11.2, 11) << std::endl;return 0;
}

3.1.13 带领域Enumeration

名称:scoped enumeration/strong enumeration/enumeration class

格式:

enum class enumname:int{...};// int 可以换成其它类型,默认就是int

注意事项:

1.绝不对隐式转换至/自int

2.如果数值不再enumeration声明的作用域内,必须使用enum name::数值

3.可以显示定义一个低层类型,获得一个保证大小。如果省去,默认为int

4.提前声明enumeration type是可能的,那会消除“为新的enumeration value而重新编译的必要”的必要–如果只是类型被使用。

#include <iostream>// 先回顾以前的枚举的定义// 带名字
enum myenum
{FAILED,SUCCESS,OUT_RANGE
};// 不带名字
enum
{FAILED1,SUCCESS1 = 2, // 可以修改值,然后后面的就是自动+1OUT_RANGE1
};// scoped enumeration
// 可以显示定义低层类型(char),并因此获得一个保证大小,不写的话默认为int
enum class Salutation : char
{mr,ms,co,none
};
// using SA = enum class Salutation: char{mr, ms,co,none}; //可以用using 起个别名,Salutation太长了。int main(int argc, char const *argv[])
{int a = OUT_RANGE1; std::cout << a << std::endl;// 1.绝不会隐式转换至/自int//  int b = SA::co; // 报错无法完成转换// 2.如果数值不在enumeration被声明的作用域内,使用enumname::数值//  int b1 = mr // mr' was not declared in this scopeint c = static_cast<int>(Salutation::none);return 0;
}

3.1.14 新的基础类型

char16_t 和char32_t

long long 和unsigned long long

std::nullptr_t

#include <iostream>
#include <memory>
int main(int argc, char const *argv[])
{std::cout << "sizeof(char16_t) = " << sizeof(char16_t) << std::endl;std::cout << "sizeof(char32_t) = " << sizeof(char32_t) << std::endl;std::cout << "sizeof(long long) = " << sizeof(long long) << std::endl;std::cout << "sizeof(unsigned long long) = " << sizeof(unsigned long long) << std::endl;std::cout << "sizeof(nullptr) = " << sizeof(nullptr) << std::endl;return 0;
}// 结果
// sizeof(char16_t) = 2
// sizeof(char32_t) = 4
// sizeof(long long) = 8
// sizeof(unsigned long long) = 8
// sizeof(nullptr) = 8

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

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

相关文章

PbootCMS在搭建网站

1、打开网站 https://www.pbootcms.com/ 2、点击 “本站” 下载最新的网站代码 3、在本地laragon/www下创建目录&#xff08;hejuwuye&#xff09;&#xff0c;并将代码放进去 4、创建本地数据库&#xff0c;数据库名称为&#xff1a; hejuwuye&#xff0c;然后将static/bac…

快速傅里叶变换

引言 目标 傅里叶变化&#xff08;Fourier transform&#xff09;是一种信号处理技术&#xff0c;它可以将时间信号转换为频率信号&#xff0c;即将一组具有相同数量频率的正弦波叠加在一起&#xff0c;形成一组新的正弦波。如果我们把时间信号从频域转换到时域&#xff0c;那么…

SLAM ORB-SLAM2(1)总体框架

SLAM ORB-SLAM2(1)总体框架 1. 简介2. 框架3. TRACKING4. LOCAL MAPPING5. LOOP CLOSING6. MAP1. 简介 ORB-SLAM2 是一个实时和完整的视觉SLAM系统(包括闭环检测、重定位、地图重用等功能) 提供了利用单目、双目以及RGB-D相机完成稀疏三维重建的功能和接口 2. 框架 总体来说…

python项目制作docker镜像,加装引用模块,部署运行!

一、创建Dockerfile # 基于python:3.10.4版本创建容器 FROM python:3.10.4 # 在容器中创建工作目录 RUN mkdir /app # 将当前Dockerfile目录下的所有文件夹和文件拷贝到容器/app目录下 COPY . /app# 由于python程序用到了requests模块和yaml模块&#xff0c; # python:3.10.4基…

二叉树进阶练习

目录 一、根据二叉树创建字符串 二、二叉树的最近公共祖先 三、二叉搜索树与双向链表 四、从前序与中序遍历序列构造二叉树 五、从中序与后序遍历序列构造二叉树 六、二叉树的前序遍历&#xff08;非递归实现&#xff09; 七、二叉树的中序遍历&#xff08;非递归实现&a…

紫光展锐5G芯T820 解锁全新应用场景,让机器人更智能

数字经济的持续发展正推动机器人产业成为风口赛道。工信部数据显示&#xff0c;2023年上半年&#xff0c;我国工业机器人产量达22.2万套&#xff0c;同比增长5.4%&#xff1b;服务机器人产量为353万套&#xff0c;同比增长9.6%。 作为国内商用服务机器人领先企业&#xff0c;云…

应用在儿童平板防蓝光中的LED防蓝光灯珠

现在电子产品多&#xff0c;手机、平板电脑、电子书等等&#xff0c;由于蓝光有害眼睛健康&#xff0c;于是市场上有很多防蓝光的眼镜、防蓝光的手机膜、防蓝光的平板&#xff0c;这些材料和设备到底有没有用&#xff1f;如何正确预防蓝光危害呢&#xff1f; 我们现在所用的灯…

NCTF-2019-Crypto部分 复现

文章目录 SorechildRSAeasyRSAbabyRSA Sore 题目描述&#xff1a; task.py from string import ascii_letters from flag import flagctoi lambda x: ascii_letters.index(x) # 获得所有字母的字符串 itoc lambda x: ascii_letters[x] # 将索引值转换为字母key flag.strip…

关于 Resolution(分辨率、解析力)各单位的意义及相互之间的换算

1、问题背景 最近在调试的项目&#xff0c;有关于对解析力的要求&#xff0c;用 imatest 软件测试 MTF50 的值&#xff0c;如下图所示&#xff0c;可以看到他有不同的单位表示&#xff0c;LW/PH、Cycles/pixel 。另外关于解析力的单位还有LP/mm、L/mm、Cycles/mm、LP/PH&#…

MySQL安装validate_password_policy插件

功能介绍 validate_password_policy 是插件用于验证密码强度的策略。该参数可以设定三种级别&#xff1a;0代表低&#xff0c;1代表中&#xff0c;2代表高。 validate_password_policy 主要影响密码的强度检查级别&#xff1a; 0/LOW&#xff1a;只检查密码长度。 1/MEDIUM&am…

jsoup框架技术文档--java爬虫--基本概念

阿丹&#xff1a; 之前使用python写的爬虫&#xff0c;但是现在项目的技术选型是需要使用jsoup来爬取网页的数据。那就需要重新学习一个框架。首先了解一下整体框架的基本概念。 jsoup的概念 JSoup是一个开源的Java库&#xff0c;它用于处理HTML文档&#xff0c;类似于一个用于…

QT tcpserver

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 服务端有QTcpServer库&#xff0c;封装了监听操作server new QTcpServer();// 直接监听&#xff0c;内部根…

Object的常用方法

目录 1.getClass()&#xff1a;获得运行时类型 2.hashCode()&#xff1a;获取哈希值 3.equals()&#xff1a;比较方法 4.clone()&#xff1a;实现对象的浅拷贝方法 5.toString()&#xff1a;输出为String 6.notify()&#xff1a;唤醒线程 7.notifyAll()&#xff1a;…

MVSNet CVPR-2018 学习总结笔记 译文 深度学习三维重建

文章目录 2 MVSNet CVPR-20182.0 主要特点2.1 过程2.2 MVSNet主要贡献2.3 论文简介2.3.1 深度特征提取2.3.2 构造匹配代价2.3.3 代价累计2.3.4 深度估计2.3.5 深度图优化2.4 MVSNet(pytorch版本)2 MVSNet CVPR-2018 MVSNet (pytorch版) 代码注释版 下载 (注释非常详细,代码…

IO流(IO Stream)

​ 一、概述 我们已经系统学习了File 类&#xff0c;并且已经知道 File 类的实例用于表示文件或目录的路径 名。 虽然我们可以通过 File 实例来访问文件或目录的元数据&#xff0c;甚至可以创建、删除文件或目 录&#xff0c;但是&#xff0c;我们却不能通过File实例来访问文…

春秋云镜 CVE-2015-1427

春秋云镜 CVE-2015-1427 ElasticSearch RCE 靶标介绍 ElasticSearch RCE 启动场景 漏洞利用 因查询时至少要求es中有一条数据&#xff0c;所以发送如下数据包&#xff0c;增加一个数据&#xff1a; POST /website/blog/ HTTP/1.1 Host: eci-2zedttamjkr80i9iubel.cloudeci…

Java基础11——抽象类和接口

Java基础11——抽象类和接口 抽象类和抽象方法 区分普通方法和抽象方法 在Java 中&#xff0c;当一个类被 abstract 关键字修饰的时候这个类称为抽象类。当一个类的方法被 abstract 关键字修饰的时候&#xff0c;该方法称为抽象 方法。抽象方法必须定义在抽象类中。当一个方…

leetcode 1921. 消灭怪物的最大数量(每日一题)

最近学习的状态找回很多。慢慢来吧&#xff0c;加油&#xff01; 1921. 消灭怪物的最大数量 你正在玩一款电子游戏&#xff0c;在游戏中你需要保护城市免受怪物侵袭。给你一个 下标从 0 开始 且长度为 n 的整数数组 dist &#xff0c;其中 dist[i] 是第 i 个怪物与城市的 初始…

Linux安装MySQL8.0

又又又又..Linux装MySQL。 删除原有的MySQL 查看安装的mysql信息&#xff1a;rpm -qa|grep -i mysql 删除mysql相关服务&#xff1a;rpm -e --nodeps 查询mysql遗留文件和依赖信息&#xff1a;find / -name mysql 手动删除mysql配置文件&#xff1a;rm -rf /etc/my.cnf 相关…

MySQL锁

MySQL锁 事务事务的隔离级别脏读&#xff0c;不可重复读&#xff0c;幻读 表锁与行锁表锁测试准备测试 行锁测试 读锁与写锁读锁&#xff08;共享锁&#xff09;测试 写锁&#xff08;排他锁&#xff09;测试 元数据锁表级元数据锁表级MDL**&#xff08;Metadata Lock&#xff…