对象移动(右值引用(&&)、移动构造函数、移动赋值运算符、引用限定函数)
原文:对象移动(右值引用(&&)、移动构造函数、移动赋值运算符、引用限定函数)
一、对象移动概述
- C++11标准引入了“对象移动”的概念
- 对象移动的特性是:可以移动而非拷贝对象
- 在C++旧标准中,没有直接的方法移动对象。因此会有很多不必要的资源拷贝
- 标准库容器、string、share_ptr类既支持移动也支持拷贝。IO类和unique_ptr类可以移动但不能拷贝
对象移动的特点
- 在很多情况下会发生对象拷贝的现象,对象拷贝之后就被销毁了,在这种情况下,对象移动而非对象拷贝会大幅度提升性能
- 使用移动而非拷贝的另一个原因是:类似于IO类或unique_ptr这样的类,这些类都不能被共享资源(如指针或IO缓冲)。因此,这些类型的对象不能拷贝但可以移动
二、右值引用(&&)
- 为了支持移动操作,C++11标准引入了新的引用类型——右值引用
- 所谓右值引用就是必须绑定到右值的引用。我们通过&&而不是&来获得右值引用
- 右值有一个很重要的性质:只能绑定到一个将要销毁的对象
右值引用的使用方法
- 左值引用:
- 不能将其绑定到要求“转换的表达式、字面值常量、返回右值的表达式”
- 返回左值的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是返回左值的表达式。我们可以将一个左值引用绑定到这类表达式的结果上
- 右值引用:
- 则与左值引用相反,我们可以将一个右值引用到上面所述的表达式上,但是不能将一个右值引用直接绑定到一个左值上
- 返回非引用类型的函数,连同算术、关系、位以及后置递增运算符,都生成右值。我们可以将一个const的左值引用或一个右值引用绑定到这类表达式上
int i = 42;
int &r = i; //正确,r引用i
int &&rr = i; //错误,不能将一个右值引用到左值上
int &r2 = i * 42; //错误,i*42是一个右值
const int &r3 = i * 42;//正确,我们可以将一个const的引用绑定到一个右值上
int &&rr2 = i * 42; //正确,将rr2绑定到乘法结果上(右值)
int ret(int i) {return i * 2;
}
int& ret2(int& i) {return i;
}int &r = ret(1); //错误
int &&rr = ret(1); //正确int &r2 = ret2(1); //正确
int &&rr2 = ret2(1); //错误
左值持久、右值短暂
- 左值一般是绑定到对象身上,因此左值是持久的
- 而右值要么绑定在字面值常量、要么绑定到表达式求值过程中创建的临时对象身上,因此:
- 右值引用所引用的对象将要被销毁
- 该对象没有其他用户
- 这两个特性意味着,使用右值引用的代码可以自由地接管所引用的对象的资源
变量是左值
- 变量可以看做只有一个运算对象而没有运算符的表达式。因此不能将一个右值引用绑定到一个右值引用类型的变量上
int &&rr1 = 42; //正确,42是字面值 int &&rr2 = rr1; //错误,表达式rr1是左值
标准库move()函数
- 虽然不能将一个右值引用绑定到一个左值上,但是我们可以显式地将一个左值转换成对应的右值引用类型
- move函数就是实现上面的功能,move函数用来获得绑定到左值上的右值引用
- 此函数定义在头文件<utility>中
int &&rr1 = 42; //正确,42是字面值 int &&rr2 = std::move(rr1); //正确了
三、移动构造函数和移动赋值运算符
- 与string一样,我们自己的类也支持移动和拷贝。为了支持移动,我们需要自己定义移动构造函数与移动赋值运算符
- 下面是一个类的定义,用来作为下面讲解的基础
lass StrVec
{
public:StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {}~StrVec() {if (elements) { //如果数组不为空//释放内存}}
private:std::string *elements; //指向数组首元素的指针std::string *first_free;//指向数组第一个空闲元素的指针std::string *cap; //指向数组尾后位置的指针
};
移动构造函数
格式如下:
- 参数为“&&”类型,因为是移动操作
- 参数不必设置为const,因为需要改变
- 在构造函数后添加“noexcept”关键字,确保移动构造函数不会抛出异常
针对上面的StrVec类,其移动构造函数的定义如下:
- noexcept确保移动构造函数不会抛出异常
- 在参数初始化列表中将参数s的资源移动给自己(先执行)
- 然后在函数体内释放参数s的资源,这样之后就达到了资源移动的目的(后执行)
StrVec(StrVec &&s) noexcept:elements(s.elements),first_free(s.first_free),cap(s.cap)
{s.elements = s.first_free = s.cap = nullptr;
}
几点需要注意:
- 移动构造函数不分配任何内存,只是简单的资源移动而已
- 参数s在资源移动之后,其对象还是存在的。当s被销毁时,其会执行析构函数,从上面StrVec的析构函数可以看出我们将elements设置为nullptr之后,析构函数就不会释放资源了(因为资源是被移动了,不应该被释放)
移动赋值运算符
格式如下:
- 参数为“&&”类型,因为是移动操作
- 参数不必设置为const,因为需要改变
- 在函数后添加“noexcept”关键字,确保移动赋值运算符函数不会抛出异常
- 与拷贝赋值运算符一样,函数返回自身引用
- 在函数执行前,应该检测自我赋值的情况
针对上面的StrVec类,其移动赋值运算符函数的定义如下:
- noexcept确保函数不会抛出异常
- 函数执行之前先判断一下是否为自我赋值
- 先释放自身资源,再拷贝参数rhs的资源,最后再将rhs置为空
trVec& operator=(StrVec &&rhs)
{//检测自我赋值,不能写成*this != sif (this != &rhs) {if (this->elements) {//释放自身的资源}//开始接管参数的资源elements = rhs.elements;first_free = rhs.first_free;cap = rhs.cap;//将参数置为空rhs.elements = rhs.first_free = rhs.cap = nullptr;}return *this;
}
为什么需要检测自我赋值:
- 我们知道,右值引用只能绑定到一个右值身上,不能绑定到一个对象身上,因此照理说移动赋值运算符不会运用于对象身上,所以检测自我赋值照理说可以取消。但是注意,我们上面介绍的move()函数,可以显式地将一个左值转换成对应的右值引用类型,因此参数可能是move()调用返回的结果(std::move(对象自身)),因此我们需要在函数运行前检测自我赋值
四、为什么需要noexcept关键字
- 由于移动操作时“移动”资源,不分配任何资源,因此移动操作通常不会抛出异常。当我们编写一个不编写异常的移动操作时,应该将此事通知标准库
我们将看到:
- 我们使用noexcept关键字通知标准库我们的移动操作函数不会抛出异常
- 否则标准库就会认为我们的移动操作函数可能会抛出异常,并且为了处理这种可能性而做一些额外的工作
为什么设计noexcept
- 为什么需要noexcept能够帮助我们深入理解标准库是如何与我们自定义的类型进行交互的
我们指定移动操作不会抛出异常,与两个事实有关:
首先,虽然移动操作通常不抛出异常,但是抛出异常还是允许的
其次,标准库容器能对异常发生时其自身的行为提供保障。例如,vector保证如果我们调用push_back发生异常,vector自身不会发生变化
我们以vector为例:
- 对一个vector调用push_back可能要求为vector重新分配内存。当重新分配内存时,vector的元素将从旧内存移动到新内存中
- 移动一个对象通常会改变它的值。如果重新分配过程中使用了移动构造函数,且在移动了部分而不是全部元素的时候抛出了一个异常,就会产生一个问题:旧内存中的元素已经被改变了,但新内存中未构造的元素可能尚不存在。在此种情况下,vector将不能满足自身保持不变的要求
- 另一方面,如果vector使用了拷贝构造函数且发生了异常,他可以很容易地满足要求。在此情况下,当在新内存中构造函数时,旧元素保持不变。如果此时发生了异常,vector可以释放新分配的内存并返回。vector原有的匀速仍然存在
- 为了避免这些潜在的问题,除非vector知道元素类型的移动构造函数不会抛出异常,否则构造在重新分配内存的过程中,它就必须使用拷贝构造函数而不是移动构造函数。如果希望在vector重新分配内存的情况下对我们自定义类型的对象进行移动而不是拷贝,就必须显式地告诉标准库我们的移动构造函数可以安全使用(通过noexcept)
五、移动后,对象仍是有效、可析构的
- 从移动操作可以看出,一个对象(在此称为“源对象”)在被移动之后,源对象仍然保持有效,因此这个对象在操作完成之后仍然可以被销毁
六、合成的移动操作
- 合成”意为“默认的”(编译器做的事)
- 对于移动操作,编译器的规则如下:
- 如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或者析构函数,编译器不会为自己合成移动构造函数和移动赋值运算符
- 只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个非static数据成员都可以移动时,编译器才会为自己合成移动构造函数或移动赋值运算符(附加:编译器可以移动内置类型成员。如果一个成员是类类型,且该类有对应的移动操作,编译器也能移动这个成员)
//编译器会为X和hasX合成移动操作
struct X {int i; //内置类型可以移动std::string s;//string定义了自己的移动操作
};struct hasX {X mem; //X有合成的移动操作
};int main()
{X x;X x2 = std::move(x); //使用合成的移动构造函数hasX hx;hasX hx2 = std::move(hx); //使用合成的移动构造函数return 0;
}
七、删除的移动操作
对于删除的移动操作有如下规则:
- 与拷贝操作不同,移动操作永远不会隐式定义为删除的(=delete)函数。
- 如果我们显示地要求编译器生成=default的移动操作,且编译器不能移动所有成员,则编译器会将移动操作定义为删除的函数
何时将合成的移动操作定义为删除的函数遵循与定义删除合成的拷贝操作类似的原则:
- ①与拷贝构造函数不同,移动构造函数被定义为删除的函数的条件是:有类成员定义了自己的拷贝构造函数且未定义移动构造函数,或者是有类成员未定义自己的拷贝构造函数且编译器不能为其合成移动构造函数(移动赋值运算符的情况类似)
- ②如果有类成员的移动构造函数或移动赋值运算符被定义为删除的或是不可访问的,则类的移动构造函数或移动赋值运算符被定义为删除的
- ③类似拷贝构造函数,如果类的析构函数被定义为删除的或不可访问的,则类的移动构造函数被定义为删除的
- ④类似拷贝赋值运算符,如果有类成员是const的或是引用,则类的移动赋值运算符被定义为删除的
移动操作和合成的拷贝控制成员之间还有最后一个关系:
- 一个类是否定义自己的移动操作对拷贝构造函数如何合成有影响
- 如果类定义了一个移动构造函数和/或一个移动赋值运算符,则该类的合成拷贝构造函数和拷贝赋值运算符是被定义为删除的
- 总结:定义了一个移动构造函数或移动赋值运算符的类必须定义自己的拷贝操作。否则,这些成员默认地被定义为删除的
//假设Y是一个类,且Y定义了自己的拷贝构造函数但未定义自己的移动构造函数
struct hasY {hasY() = default;hasY(hasY &&) = default;Y mem; //Y是一个类,且Y定义了自己的拷贝构造函数但未定义自己的移动构造函数
};int main()
{hasY hy;hasY hy2 = std::move(hy); //错误,移动构造函数是删除的return 0;
}
//StrVec只定义了移动构造函数与移动赋值运算符,但是没有定义拷贝构造函数与拷贝赋值运算符
class StrVec
{
//...
public:StrVec(StrVec &&s)noexcept{}StrVec& operator=(StrVec &&rhs){}
//...
};int main()
{StrVec v1, v2;v1 = v2; //错误,SreVec的拷贝赋值运算符被定义为删除的return 0;
}
八、移动右值、拷贝左值
- 如果类既有“”移动构造函数,也有“拷贝构造函数”,编译器使用普遍的函数匹配机制来缺点使用哪个构造函数
//假设SreVec的拷贝构造函数/拷贝赋值运算符,移动构造函数/移动拷贝赋值运算符都定义了
class StrVec{};StrVec getVec(istream &)
{//该函数返回一个SreVec对象(右值)
}int main()
{StrVec v1, v2;v1 = v2; //v2是个左值,此处调用拷贝赋值运算符v2 = getVec(cin); //getVec函数返回一个右值,此处调用移动赋值运算符return 0;
}
如果没有定义移动构造函数,右值也被拷贝
- 如果一个类有一个拷贝构造函数但未定义移动构造函数,那么:
- 因为类有了拷贝构造函数,编译器不会合成移动构造函数
- 所以,对于右值的移动操作时调用拷贝构造函数的
- 上面的规则也适用于拷贝赋值运算符
class Foo {
public:Foo() = default; Foo(const Foo&); //拷贝构造函数//未定义移动构造函数
};int main()
{Foo x;Foo y(x); //调用拷贝构造函数Foo z(std::move(x));//因为Foo没有定义移动构造函数,所以此处调用的是拷贝构造函数return 0;
}
- 使用拷贝构造函数代替移动构造函数几乎肯定是安全的(赋值运算符情况类似)。一般情况下,拷贝构造函数满足对应的移动构造函数的要求:它会拷贝给定对象,并将源对象置于有效状态。实际上,拷贝构造函数甚至都不会改变源对象的值
九、拷贝并交换赋值运算符和移动操作
class HasPtr {
public:HasPtr(const std::string &s = std::string()):ps(new std::string(s)), i(0) {}HasPtr(const HasPtr& p) //拷贝构造函数:ps(new std::string(*(p.ps))), i(p.i) {}~HasPtr() { delete ps; }friend void swap(HasPtr&, HasPtr&);
private:std::string *ps;int i;
};inline void swap(HasPtr &lhs, HasPtr &rhs)
{using std::swap;swap(lhs.ps, lhs.ps);//交换指针,而不是string数据swap(lhs.i, lhs.i); //交换int成员}
- 现在我们为HasPtr类添加了一个移动构造函数和一个赋值运算符(这个赋值运算符比较特殊)
lass HasPtr {
public://其他内容同上//移动构造函数HasPtr(HasPtr &&p)noexcept :ps(p.ps), i(p.i) { p.ps = 0; }//这个赋值运算符即是移动赋值运算符,也是拷贝赋值运算符HasPtr& operator=(HasPtr rhs){swap(*this,rhs);return *this;}
};
移动构造函数
- 移动构造函数接管了给定实参的值、函数体内将p的指针置为0,从而确保销毁源对象是安全的
- 此函数不会抛出异常,因此将其标记为noexcept
赋值运算符
- 此处定义的赋值运算符的参数不是引用形式,意味着此参数要进行拷贝初始化
- 依赖实参的类型,拷贝初始化:
- 要么使用拷贝构造函数——左值被拷贝
- 要么使用移动构造函数——右值被移动
- 因此,此处定义的赋值运算符就实现了拷贝赋值运算符和移动赋值运运算符的两种功能
例如:
- 第一个赋值中,右侧对象hp2是一个左值,因此使用拷贝构造函数来初始化
- 第二个赋值中,我们调用std::move()将将一个右值绑定到hp2上。此种情况下,拷贝构造函数和移动构造函数都是可以的。但是由于实参是一个右值引用,移动构造函数时精确匹配的
HasPtr hp;
HasPtr hp2;//hp2是一个左值。所以先调用拷贝构造函数复制一份HasPtr对象给operator=参数
//再调用operator=函数将hp2赋值给hp
hp = hp2;//此处hp2显式成为一个右值。所以先调用移动构造函数构造一份HasPtr对象给operator=参数
//再调用operator=函数将hp2赋值给hp
hp = std::move(hp2);
- 不管使用的是拷贝构造函数还是移动构造函数,赋值运算符的函数体内都swap两个对象的状态。交换HasPtr回交换两个对象的指针(及int)成员。在swap之后,rhs中的指针将指向原来左侧对象所拥有的string(及int)。当rhs离开作用域后,这个对象将会销毁
十、右值引用和成员函数
除了构造函数和赋值运算符之外,成员函数也可能提供两个版本:一个提供拷贝,另一份通过移动
- 一份提供拷贝:参数为const&
- 一份提供移动:参数为非const&&
使用规则:
- 对于拷贝版本:我们可以将任何类型的对象传递给该版本
- 对于移动版本:只能传递给其非const的右值
- 一般来说,我们不需要为函数定义接受一个const T&&或是一个(普通的)T&参数的版本。当我们希望从实参“窃取”数据时,通常传递一个右值引用。为了达到这个目的,实参不能使const的。类似的,从一个对象进行拷贝的操作不应该改变该对象,因此,通常不需要定义一个接受(普通的)T&参数的拷贝版本
演示案例
- 对于push_back的标准库容器提供两个版本:
- 一个版本有一个右值引用
- 另一个版本有一个const左值引用
- 例如:
void push_(const X&); //拷贝版本
void push_(X&&); //移动版本
演示案例
- 作为更好的例子,我们将StrVec类进行修改,在其中添加了两个push_back()函数
class StrVec
{
public://其他同上void push_back(const std::string&);//拷贝元素void push_back(std::string&&); //移动元素
private:static std::allocator<std::string> alloc; //分配元素//其他同上
};void StrVec::push_back(const std::string& s)
{chk_n_alloc(); //自定义函数,用来检测是否空间足够//在first_free指向的元素中构造s的一个副本,此处construct会调用string的构造函数来构造新元素alloc.construct(first_free++, s);
}void StrVec::push_back(std::string&&)
{chk_n_alloc();//此处由于参数为std::move()类型,因此construct会调用string的移动构造函数来构造新元素alloc.construct(first_free++,std::move(s));
}
- 当我们调用push_back()时,实参类型决定了新元素是拷贝还是移动到容器中:
StrVec vec;
string s = "some string or another";vec.push_back(s); //s为左值,因为调用push_back(const string&)
vec.push_back("done"); //调用push_back(string&&)
十一、右值和左值引用成员函数(引用限定函数)
- 通常,我们在一个对象上调用成员函数,而不管该对象是一个左值还是一个右值:例如:
string s1 = "a value", s2 = "another";//s1+s2是一个右值
auto n = (s1 + s2).find('a');
- 有时候,右值的使用还可能是下面的奇怪形式
string s1 = "a value", s2 = "another";
s1 + s2 = "wow"; //s1+s2是一个右值,我们此处对一个右值进行了赋值(无意义)
- 在旧标准中,我们没有办法阻止这种使用方式。为了维持向后兼容性,新标准库类仍然允许向右值赋值。但是,我们可以在自己的类中阻止这种办法。在此情况下,我们希望强制左侧运算对象是一个左值
使用方法:
- 在参数列表后放置一个引用限定符
- 引用限定符可以是&或&&,分别该函数可以运用于一个左值对象(&)还是一个右值对象(&&)
- 与const关键字一样,引用限定符只能作用于(非static)成员函数,且在声明和定义时都需要
- 引用限定符可以和const一起使用,且const必须在限定符的前面。例如:
class Foo {
public:Foo someMem()&const; //错误,const必须在&&前面Foo anotherMem()const&;//正确
};
演示案例
class Foo {
public://此参数后面有一个&,因此这个函数只能被一个左值对象调用Foo &operator=(const Foo&)&;
};Foo &Foo::operator=(const Foo& rhs)&
{//执行将rhs赋予本对象的操作(代码省略)return *this;
}
- 在上面我们在operatror=的后面添加了一个&,因此operatror=只能运用于一个左值,见下面的代码
Foo& retFoo()
{//一个函数,返回Foo类,返回左值(引用)
}Foo retVal()
{//一个函数,返回Foo类,返回右值
}int main()
{Foo i, j;i = j;retFoo() = j; //正确,retFoo()返回一个左值retVal() = j; //错误,retVal()返回一个右值i = retFoo(); //正确,我们可以将一个左值作为赋值操作的右侧运算对象i = retVal(); //正确,我们可以将一个右值作为赋值操作的右侧运算对象return 0;
}
演示案例②
class Foo {
public:void push_back() && {} //这个函数只能被一个右值Foo对象调用
};Foo& retFoo()
{//一个函数,返回Foo类,返回左值(引用)
}Foo retVal()
{//一个函数,返回Foo类,返回右值
}int main()
{Foo i;i.push_back(); //错误,i是一个左值retFoo().push_back(); //错误retVal().push_back(); //错误(retVal应该返回右值的啊,但是编译器报错)std::move(retVal()).push_back();//正确return 0;
}
演示案例
class Foo {
public://此函数只可以用于右值Foo sorted() && {std::sort(data.begin(), data.end());return *this;}//此函数可以用于左值或const类型的右值(因为其带有const,见下面的重载介绍)Foo sorted()const & {Foo ret(*this); //拷贝一个副本std::sort(ret.data.begin(), ret.data.end()); //排序副本return ret; //返回结果}
private:std::vector<int> data;
};Foo& retFoo()
{//一个函数,返回Foo类,返回左值(引用)
}Foo retVal()
{//一个函数,返回Foo类,返回右值
}const Foo retVal2()
{//一个函数,返回Foo类,返回右值,且为const
}int main()
{retFoo().sorted(); //调用sorted()const&retVal().sorted(); //调用sorted() &&retVal2().sorted();//调用sorted()const&return 0;
}
- 对于sorted() &&:如果对象是一个右值,意味着没有其他用户,因此我们可以在函数内改变对象的内容
- 对于sorted()const&:如果对一个const右值或一个左值执行sorted时,我们不能改变对象,因此就需要在里面使用拷贝的临时对象进行排序,然后将结果返回
十二、重载和引用函数
- const成员函数重载时,可以定义两个版本:一个有const、一个没有const
class Foo {
public://下面两者形成重载Foo sorted();Foo sorted()const;
};
- 引用限定函数规则不一样:重载时必须两者都加上引用限定符
class Foo {
public:Foo sorted()&&;Foo sorted()const&&; //正确,与上面形成重载//Foo sorted()const; 这个是错误的
};
- 附加:如果一个成员函数有引用限定符,则具有相同参数列表的所有版本都必须有引用限定符
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- MongoDB安装完后的几个问题
系统:win7 64位 MongoDB版本: 4.2.7 1.mongo不是内部或外部命令 添加环境变量 "...\MongoDB\Server\4.2\bin (mongo.exe所在文件夹路径) 2.运行 mongo命令出现"Error:couldn’t connect to server…" 这是因为没有启用MongoDB服务,手动启用命令: net start …...
2024/4/16 10:02:50 - git 仓库之间的代码合并
上篇讲了仓库A迁移到B仓库 但是是已存在的仓库A和不存在的仓库B之间的代码迁移 本篇讲下 已经存在的项目A 已经存在的项目B 仓库A的代码迁移到仓库B1.首先进入终端打开仓库目的仓库B的目录2.我想把仓库A的代码提交到仓库B的master分支3.首先切换分支 git checkout master4.将仓…...
2024/4/18 3:56:03 - Linux笔记(一)
一:开始下达命令[dmtsai@study ~]$ command [-options] parameter1 parameter2 …[dmtsai@study ~]$ command [-options] parameter1 parameter2指令 选项 参数(1) 参数(2)上述指令详细书说明:指令中第一个输入的部分绝对是“指令(command)” 或“可执行文件案(例如批…...
2024/4/19 19:11:43 - 为什么要使用celery,以及broker的选择标准
celery是什么? Celery是基于Python开发的一个分布式任务队列框架,支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度 celery的使用场景?有延时需要网络IO的,并且不关心返回结果的数据。例如:你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让…...
2024/4/16 10:02:40 - gitlab添加qq邮箱smtp配置
概述 在安装gitlab后, 未添加邮件提供功能(比如,添加一个用户,就给他发邮件提醒),需要配置发邮件的 smtp 服务器配置。 配置 此处使用个人的qq邮箱配置 smtp。 也就是发邮件通知时,发件人邮箱地址是这个 qq邮箱。 配置如下: vim /etc/gitlab/gitlab.rb 找到 gitlab_rai…...
2024/4/20 10:05:54 - 基于Spring Boot实现邮箱获取验证码进行注册
前置技能:1.创建spring boot项目(博客链接:点击跳转) 2.整合mybatis框架(博客链接:点击跳转) 3.热加载(并不必要,但是部署了测试项目会方便很多,博客链接:点击跳转) 4.基于mybatis和spring boot实现对mysql的增删改查(博客链接:点击跳转) 5.基于Spring Boot框架实现发送邮件(博…...
2024/4/16 10:02:55 - c++实现将实数转化为分子分母都为整数的分数。
real_value* translation_util::real_to_fraction(float num){//分子.long long nume = 0;//分母.long long denom = 1;bool flag = false;char ch;string str = std::to_string(num);//得到分子分母.for(int i = 0; i < (int)str.length(); i++){ch = str[i];if(ch == .){f…...
2024/4/19 12:33:07 - Java学习笔记15常用类_20200601
这里写自定义目录标题第15章 常用类15.01 练习15.02 Object类 第15章 常用类 15.01 练习 (见上一章 最后一项) 15.02 Object类...
2024/4/17 23:13:53 - kubectl源码分析之delete
发布一个k8s部署视频:https://edu.csdn.net/course/detail/26967课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。腾讯课堂连接地址https://ke.qq.com/course/478827?taid=4373…...
2024/4/16 10:02:55 - 第一天
路径: 路径有相对路径和绝对路径。 相对路径 1,引用同一级的图片< img src =“sun.jpg” > 2,引用下一级的图片< img src="image/sun.jpg > 3,引用上一级的图片html文件夹里面的页面demo.html需要引用存放在image文件夹里面的sun.jpg,那么demo需要先返回到…...
2024/4/16 10:02:35 - SpringBoot整合Websocket实现消息推送
效果显示: 客户端 http://localhost:80/index服务端 http://localhost:80/admin客户端A连接并发送消息服务端服务端单发消息服务端群发消息点击这里>Github项目源码地址-SpringBoot整合Websocket实现消息推送...
2024/4/19 13:40:41 - Python服务器运维笔记:第二章Linux - 1.2.10 多线程
前言:本文是学习网易微专业的《python全栈工程师》 中的《服务器运维开发工程师》专题的课程笔记,欢迎学习交流。同时感谢老师们的精彩传授!一、课程目标多线程概念 多线程实现 多线程server socket二、详情解读 2.1.什么是多线程 什么是进程? 我们每运行一个程序,就是创建…...
2024/4/16 10:02:45 - 记一次Spring项目打包问题排查
一个 Spring 项目,打成 jar 包之后运行,在有网络的时候是正常的,但是一旦无网络就会报错,具体是怎么回事呢?这篇文章就来记录下这次问题排查经过。背景介绍 一个图形化的界面,带本地数据库,要求可以在无网络环境下运行,我帮朋友用的 Java 写的图形化界面,虽然不是很美…...
2024/4/16 10:02:50 - 0525 0601零散问题整理
1. React Component父子组件间传值 1.1 Parent to Child — Use Prop class App extends React.Component {render() {[... somewhere in here I define a variable listName which I think will be useful as data in my ToDoList component...]return (<div><InputB…...
2024/3/30 2:36:10 - 查表的时候锁行
...
2024/4/16 10:03:36 - git保存用户密码(linux)
1.查看当前密码保存策略 ,如果没有需要设置git config credential.helper2.设置全局credential.helper为storegit config --global credential.helper store3.该配置会保存在~/.gitconfig内4.到git项目下,使用get pull,输入用户名密码即可把用户密码保存,后续就不需要输入了…...
2024/4/16 10:03:46 - 彻底关掉笔记本触摸屏
彻底关闭触摸板 自己重装了系统,FN+F几无法关闭触摸屏,平时自己打代码手误触,烦得很! 给大家介绍彻底关闭触摸板的方法设备管理器->找到鼠标和其他指针设备->双击PS/2兼容鼠标->驱动程序->驱动程序详细信息->查看驱动程序文件位置(C:\Windows\System32\driv…...
2024/4/16 10:03:46 - python实现数据仓库ETL
通常讲的数据仓库ETL, 可以分为ETL和ELT两种实现方式. ELT是在加载到仓库后, 再做数据转换. ETL 是在加载之前完成转换, 落地的数据就是转换后的样子了.ELT多使用在MPP架构的数据仓库平台上, 比如Teradata, greenplum, 主要考虑点是, MPP数据仓库数据处理能力强, 在加载后再做…...
2024/3/14 8:06:56 - 十大算法之Dijkstra
package com.atguigu.dijkstra;import java.util.Arrays;public class DijkstraAlgorithm {public static void main(String[] args) {char[] vertex = { A, B, C, D, E, F, G };//邻接矩阵int[][] matrix = new int[vertex.length][vertex.length];final int N = 65535;// 表示…...
2024/4/16 10:03:36 - 泰迪公司简介
泰迪公司简介泰迪科技是一家专业从事大数据挖掘技术及人工智能技术研发、咨询的高科技企业,是国内具有较强竞争力的大数据解决方案提供商。办公及实训场地面积近2000平方米,建有国内一流的大数据 + 人工智能产品体验展厅。 图1 办公场地公司先后通过了广州市科技创新小巨人企…...
2024/4/16 10:03:41
最新文章
- html select 支持内容过滤列表 -bootstrap实现
实现使用bootstrap-select插件 http://silviomoreto.github.io/bootstrap-select <!DOCTYPE html> <html> <meta charset"UTF-8"> <head><title>jQuery bootstrap-select可搜索多选下拉列表插件-www.daimajiayuan.com</title>&…...
2024/4/20 23:59:20 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 【虚幻引擎】C++ slate全流程开发教程
本套课程介绍了使用我们的虚幻C去开发我们的编辑器,扩展我们的编辑器,设置我们自定义样式,Slate架构设计,自定义我们的编辑器样式,从基础的Slate控件到我们的布局,一步步的讲解我们的的Slate基础知识&#…...
2024/4/19 17:30:07 - 计算机专业在找工作时的注意事项
目录 说在前面关于我一些忠告关于简历关于银行写在最后 说在前面 满满的求生欲。我不是什么大佬,更没有能力教大家什么。只是看到有不少学弟学妹,还在为找一份工作焦头烂额,却没有努力的方向。所以这里斗胆给计算机相关专业的学弟学妹们的一…...
2024/4/16 21:43:25 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/4/19 14:24:02 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/19 18:20:22 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/19 11:57:31 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/4/20 23:26:47 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/19 11:57:52 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/19 11:57:53 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/19 11:58:14 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/19 11:58:20 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/20 7:40:48 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/19 11:58:39 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/19 11:58:51 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/20 3:12:02 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/19 11:59:15 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/19 11:59:23 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/4/19 11:59:44 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/19 11:59:48 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/19 12:00:06 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/20 21:12:02 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/4/19 12:00:25 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/19 12:00:40 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57