C++11特性--右值引用,移动语义,强制移动move()
来源:互联网 发布:电脑超频软件 编辑:程序博客网 时间:2024/05/01 12:26
1.右值引用
*右值:不能对其应用地址运算符的值。
*将右值关联到右值引用导致该右值被存储到特定的位置,且可以获取该位置的地址
*右值包括字面常量(C风格字符串除外,它表示地址),诸如X+Y等表达式以及返回值得函数(条件是该函数返回的不是引用)
*引入右值引用的主要目的之一是实行移动语义
Example:
int f(int x,int y)
{
return x+y;
}
int main()
{
int a=1;
int b=2;
int &&rab=a+b;//rab关联的是a+b计算的结果,即使以后修改了a,b的值也不会影响到rab
cout<<"rab: "<<rab<<endl;//rab: 3
a=2;
cout<<"rab: "<<rab<<endl;//rab: 3
cout<<"&rab: "<<&rab<<endl<<endl;//&rab 0x22fe30
int &&rf=f(a,b);
cout<<rf<<endl;//4
return 0;
}
2.移动语义和右值引用
*移动语义实际上避免了移动原始数据,而只是修改了记录。
*要实现移动语义,需要采取某种方式,如移动构造函数(它使用右值引用作为参数,该引用关联到右值实参),移动赋值运算符
*移动构造函数可能修改其实参,这意味着右值引用参数不应是const
Tips:实现移动语义的关键在于,采取某种方式(移动构造函数,移动赋值运算符),并非真正地移动数据,而只是转交所有权(复制地址)
Example:
class mymove
{
private:
int n;
char *pt;
public:
mymove(char ch,int m):n(m)//创建包含i个ch的字符数组
{
pt=new char[m];
for(int i=0;i<m;i++ )
{
pt[i]=ch;
}
}
mymove(mymove& other)//复制构造函数
{
n=other.n;
pt=new char[other.n];
for(int i=0;i<n;i++)
{
pt[i]=other.pt[i];
}
}
mymove(mymove&& other)//移动复制构造函数
{
n=other.n;
pt=other.pt;
other.pt=nullptr;
other.n=0;
cout<<"move constructor call"<<endl;
}
mymove& operator=(mymove&& other)//移动赋值操作符
{
delete [] pt;
n=other.n;
pt=other.pt;
other.pt=nullptr;
other.n=0;
cout<<"move assignment operator call"<<endl;
return *this;
}
mymove operator+(mymove& other)
{
mymove tem(*this);
delete [] pt;
pt=new char[n+other.n];
for(int i=0;i<n;i++)//复制tem.pt中的数据
{
pt[i]=tem.pt[0];
}
for(int j=0;j<other.n;j++)//复制other.pt中的数据
{
pt[n+j]=other.pt[j];
}
n=other.n+tem.n;
cout<<"operator+()"<<endl;
return *this;
}
void print() //打印mymove.pt中的数据
{
for(int i=0;i<n;i++)
{
cout<<pt[i]<<ends;
}
}
};
int main()
{
mymove a('a',1);
a.print();//a
cout<<endl;
mymove b('b',2);
b.print();//b b
cout<<endl;
mymove c(a+b);
c.print();// a b b
cout<<endl;
a=b+c;
a.print();// b b a b b
cout<<endl;
return 0;
}
3. 强制移动move()
*头文件#include<utility>
*如果类定义了移动赋值运算符,则强制使用移动赋值运算符
Example:
class mymove
{
public:
mymove& operator=(mymove& other)
{
cout<<"operator=()"<<endl;
}
mymove& operator=(mymove&& other)
{
cout<<"move operator=()"<<endl;
}
};
int main()
{
mymove a,b;
a=b;
cout<<endl;
a=move(b);
cout<<endl;
return 0;
}
output:
operator=()
move operator=()
*右值:不能对其应用地址运算符的值。
*将右值关联到右值引用导致该右值被存储到特定的位置,且可以获取该位置的地址
*右值包括字面常量(C风格字符串除外,它表示地址),诸如X+Y等表达式以及返回值得函数(条件是该函数返回的不是引用)
*引入右值引用的主要目的之一是实行移动语义
Example:
int f(int x,int y)
{
return x+y;
}
int main()
{
int a=1;
int b=2;
int &&rab=a+b;//rab关联的是a+b计算的结果,即使以后修改了a,b的值也不会影响到rab
cout<<"rab: "<<rab<<endl;//rab: 3
a=2;
cout<<"rab: "<<rab<<endl;//rab: 3
cout<<"&rab: "<<&rab<<endl<<endl;//&rab 0x22fe30
int &&rf=f(a,b);
cout<<rf<<endl;//4
return 0;
}
2.移动语义和右值引用
*移动语义实际上避免了移动原始数据,而只是修改了记录。
*要实现移动语义,需要采取某种方式,如移动构造函数(它使用右值引用作为参数,该引用关联到右值实参),移动赋值运算符
*移动构造函数可能修改其实参,这意味着右值引用参数不应是const
Tips:实现移动语义的关键在于,采取某种方式(移动构造函数,移动赋值运算符),并非真正地移动数据,而只是转交所有权(复制地址)
Example:
class mymove
{
private:
int n;
char *pt;
public:
mymove(char ch,int m):n(m)//创建包含i个ch的字符数组
{
pt=new char[m];
for(int i=0;i<m;i++ )
{
pt[i]=ch;
}
}
mymove(mymove& other)//复制构造函数
{
n=other.n;
pt=new char[other.n];
for(int i=0;i<n;i++)
{
pt[i]=other.pt[i];
}
}
mymove(mymove&& other)//移动复制构造函数
{
n=other.n;
pt=other.pt;
other.pt=nullptr;
other.n=0;
cout<<"move constructor call"<<endl;
}
mymove& operator=(mymove&& other)//移动赋值操作符
{
delete [] pt;
n=other.n;
pt=other.pt;
other.pt=nullptr;
other.n=0;
cout<<"move assignment operator call"<<endl;
return *this;
}
mymove operator+(mymove& other)
{
mymove tem(*this);
delete [] pt;
pt=new char[n+other.n];
for(int i=0;i<n;i++)//复制tem.pt中的数据
{
pt[i]=tem.pt[0];
}
for(int j=0;j<other.n;j++)//复制other.pt中的数据
{
pt[n+j]=other.pt[j];
}
n=other.n+tem.n;
cout<<"operator+()"<<endl;
return *this;
}
void print() //打印mymove.pt中的数据
{
for(int i=0;i<n;i++)
{
cout<<pt[i]<<ends;
}
}
};
int main()
{
mymove a('a',1);
a.print();//a
cout<<endl;
mymove b('b',2);
b.print();//b b
cout<<endl;
mymove c(a+b);
c.print();// a b b
cout<<endl;
a=b+c;
a.print();// b b a b b
cout<<endl;
return 0;
}
3. 强制移动move()
*头文件#include<utility>
*如果类定义了移动赋值运算符,则强制使用移动赋值运算符
Example:
class mymove
{
public:
mymove& operator=(mymove& other)
{
cout<<"operator=()"<<endl;
}
mymove& operator=(mymove&& other)
{
cout<<"move operator=()"<<endl;
}
};
int main()
{
mymove a,b;
a=b;
cout<<endl;
a=move(b);
cout<<endl;
return 0;
}
output:
operator=()
move operator=()
- C++11特性--右值引用,移动语义,强制移动move()
- C++11新特性:移动语义和右值引用
- c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用
- c++11移动语义右值引用
- C++11特性:右值引用与move语义
- c++ 特性: 右值引用与移动语义
- c++move语义与右值引用
- [C++] 右值引用:移动语义与完美转发
- 右值引用,移动语义,完美转发
- 右值引用 移动语义 完美转发
- C++11右值引用:移动语义和完美转发
- std::move C++11 标准新特性: 右值引用与转移语义
- std::move C++11 标准新特性: 右值引用与转移语义
- C++11新特性之 Move semantics(移动语义)
- C++11 中 的Move语义 和 右值引用
- C++11中的右值引用及move语义编程
- C++11右值引用和move语义
- C++11中的右值引用及move语义编程
- 丰盛的范德萨
- hdu 2209 BFS + 状态压缩
- 黑马程序员--java基础加强-反射
- 图算法应用
- 自定义 HTTP 模块
- C++11特性--右值引用,移动语义,强制移动move()
- 开源免费的C/C++网络库(c/c++ sockets library)
- Web页面的仿plsql功能的实现
- 使用jConsole监视JVM
- Linux命令:lrzsz、sz filename、rz
- Linux系统网络配置详解
- PODOFO。Window。Cmake ---- (一) 编译
- 网易运营程序开发面经
- Cannot create JDBC driver of class '' for connect URL 'null'