多渠道营销平台与crm,房产网站关键词优化,qq空间网站根目录,怎么做营销左值与右值
字面意思是可以放在等号左边的就是左值#xff0c;只能放在等号右边的就是右值#xff08;为何是“可以”“只能”#xff1f;例如i是左值#xff0c;但他依然可以放在等号右边#xff09;。 严格上的定义#xff1a;可以取地址的就是左值#xff0c;反之为…左值与右值
字面意思是可以放在等号左边的就是左值只能放在等号右边的就是右值为何是“可以”“只能”例如i是左值但他依然可以放在等号右边。 严格上的定义可以取地址的就是左值反之为右值不具名。
左值引用
使用方法在类型后加 。 只能引用左值或加const关键字来引用右值但不能修改此情况与使用引用的目的相违背使用引用的目的就是为了修改所以一般不用。
右值引用
C11新引入只能引用右值。 使用方法在类型后加如T 。 作用延长右值生命周期减少对象的复制提升性能。
//右值引用
class X {
public:X() {cout X() endl;}X(const X x) {cout X(const X x) endl;}~X() {cout ~X() endl;}
};X makeX() {X x1;return x1;
}int main() {X x2 makeX();return 0;
}以上代码中调用makeX()如果不是右值引用需要发生两次拷贝三次构造如果用右值引用makeX()返回的将亡值延长生命周期只发生一次拷贝提升性能。但目前很多编译器都已经对此进行了返回值优化所以在大部分场景无需刻意纠结。
复制构造器与移动构造器
复制构造器形参是一个左值引用。 移动构造器接受一个右值没有了复制构造中的内存复制。 移动复制构造器的风险如果一个对象移动到另一个对象时发生异常造成目标对象不完整后果无法预测所以移动构造需要加noexcept关键字。
class MyString {
public:MyString() :str(nullptr), len(0) {}MyString(const char* ch) :str(nullptr), len(0) {if (ch ! nullptr) {len strlen(ch);str new char[len 1];strcpy(str, ch);cout Constructor endl;}}//拷贝构造函数MyString(const MyString other) :str(nullptr), len(0) {if (other.str ! nullptr) {len other.len;str new char[len 1];strcpy(str, other.str);cout Copy Constructor endl;}}//移动构造函数MyString(MyString other) :str(nullptr), len(0) {str other.str;len other.len;other.str nullptr;other.len 0;cout Move Constructor endl;}~MyString() {if (str ! nullptr) {delete[] str;str nullptr;len 0;}}private:char* str;size_t len;
};int main() {MyString string1(Test);MyString string2(string1);MyString string3(move(string1));return 0;
}注使用msvc编译以上代码的时候ide可能会出现如下的错误 error C4996: ‘strcpy’: This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. vs中在“项目右键–属性–C/C --预处理器–预处理器定义”中添加上“_CRT_SECURE_NO_WARNINGS”即可。 以上代码中move()的作用将对象的状态或所有权从一个对象转移到另一个对象将左值引用转化为右值引用继而可通过右值引用使用该值以用于移动语义。
万能引用
形如T或auto 并且发生类型推导的引用包括模板和auto如 //万能引用template class TT test(T t){}auto x get_val();完美转发
特性在函数内部完美地转发函数实参原始类型和值类型也就是说如果函数传入的实参是左值引用转发时保持实参的左值引用属性和左值引用类型。 完美转发的原理基于引用折叠即实际类型和模板类型只要有左值引用参与进来最后推导的结果就是一个左值引用遇左则左。 两种实现方式 1使用static_cast
static_castT (t);2使用标准库中forward()方法
forwardT(t);注forward()与move()的区别move()将一个实参转换为右值引用并且move()不需要模板实参。