欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++入门教程之转移语义实例

程序员文章站 2022-05-25 12:14:47
C++入门教程之转移语义实例 这里继续讲左值和右值。 由于标准库中尤其是容器库还有字符串类,对右值进行了特殊的优化: // 复制右值就等于浪费资源, 所以直接保存右值,...

C++入门教程之转移语义实例

这里继续讲左值和右值。

由于标准库中尤其是容器库还有字符串类,对右值进行了特殊的优化:

// 复制右值就等于浪费资源, 所以直接保存右值, 几乎不耗时间
std::u32string text1 = std::u32string(U"小古银是个美男子");

// 复制text1的字符串, 即复制左值, 字符串越长, 需要的时间就越长
std::u32string text2 = text1;

基础示例

如果我想交换text1和text2保存的值时,举个完整的例子:

#include  // std::cout std::endl
#include  // std::u32string

int main(void)
{
    std::u32string text1 = std::u32string(U"小古银是个美男子");
    std::u32string text2 = std::u32string(U"小古银不是个大胖小子");
    std::u32string text3; // 用来交换的中间变量

    std::cout << "交换前text1的字符数:" << text1.size() << std::endl;
    std::cout << "交换前text2的字符数:" << text2.size() << std::endl;

    text3 = text1; // text3复制text1保存的字符串
    text1 = text2; // text1复制text2保存的字符串
    text2 = text3; // text2复制text3保存的字符串

    std::cout << "交换后text1的字符数:" << text1.size() << std::endl;
    std::cout << "交换后text2的字符数:" << text2.size() << std::endl;

    return 0;
}

输出结果:

交换前text1的字符数:8
交换前text2的字符数:10
交换后text1的字符数:10
交换后text2的字符数:8

基础讲解

text3 = text1; // text3复制text1保存的字符串
text1 = text2; // text1复制text2保存的字符串
text2 = text3; // text2复制text3保存的字符串

这三行代码是交换text1和text2的代码。我们知道复制是需要内存和时间的,而现在我们想交换text1和text2,即text1的值给text2,text2的值给text1。这个时候,我们就需要转移。以上三行交换代码可以改成以下三行:

text3 = std::move(text1); // text1保存的字符串转移到text3, text1空, text2和text3非空
text1 = std::move(text2); // text2保存的字符串转移到text1, text2空, text1和text3非空
text2 = std::move(text3); // text3保存的字符串转移到text2, text3空, text1和text2非空

这样就可以不需要复制字符串而交换两个变量保存的值了。

我们再深入了解一下转移函数std::move(),他在utility标准库中。

实际上,std::move()的实现的功能很简单:它把传进来的左值还有右值都转换成右值。

std::move()返回实际参数的右值,然后再配合容器库和字符串类对右值的优化,这样就可以实现转移的语义。上面三行代码中,text3 = std::move(text1);将text1保存的值转移到text3中,此时text1保存的是空字符,接下来两行代码同理。

由于是字符串类进行了优化,对于基本数据类型,std::move()仅仅只有左值转右值的功能而没有转移的功能。如下:

#include  // std::cout std::endl
#include  // std::move

int main(void)
{
    int a = 2333;
    int b = std::move(a);
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    return 0;
}

输出结果:

2333
2333