本篇内容介绍了“C++ move semantic移动语义是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
在说移动语义之前 让我们先来说说移动构造这玩意
我们都知道 深拷贝是会把在堆区的内存一起拷贝的 那么如果我们明确知道一个对象并不会再继续使用 但是同时我们又想拿到他堆区的资源的时候 我们应该怎么办呢? 移动构造给我们提供了这种能力 代码如下所示:
class MoveClass
{
public:
int* p;
MoveClass()
{
p = new int();
std::cout << "默认构造调用" << std::endl;
}
~MoveClass()
{
std::cout << "析构函数调用" << std::endl;
if (!p)
delete p;
}
MoveClass(MoveClass& tmp)
{
}
MoveClass(MoveClass&& tmp)
{
std::cout << "移动构造函数调用" << std::endl;
this->p = tmp.p;
tmp.p = nullptr;
}
MoveClass& operator=(MoveClass&& tmp)
{
std::cout << "移动构造函数调用" << std::endl;
this->p = tmp.p;
tmp.p = nullptr;
}
};
MoveClass MoveClassTest(MoveClass d)
{
return MoveClass();
}
int main()
{
MoveClass cc;
//好 接下来我们不再想使用c了 但是堆区的资源我们并不想拷贝 那么使用如下构造方式
MoveClass d(std::move(cc));
system("pause");
}
移动前数据如下图所示:
移动后数据如下图所示:
程序输出结果:
设想一个场景 我们在一个作用域申请了一个超级大的string 如下图所示
#include <iostream>
#include <string.h>
void test1(std::string s)
{
std::cout << "test1:" << s.c_str()<<std::endl;;
}
void test()
{
std::string s = "超级大的string";
test1(s);
std::cout <<"test:"<< s.c_str() << std::endl;
return;
}
int main()
{
test();
system("pause");
}
运行结果如下:
你们就要说了 有啥用啊 但是只要你懂一点c++ 你就会知道 在test中的s我们是不需要了的 也就是我们在test是不想再继续使用s的 但是在我们调用test1的时候 我们又重新拷贝了s一份 那么性能是不是就浪费了呢?如果这个string超级大 你的程序是不是就很垃呢
我们只需要简简单单的加一个std::move 他就不是拷贝 而只是单纯的移动指针 如下
#include <iostream>
#include <string.h>
void test1(std::string s)
{
std::cout << "test1:" << s.c_str()<<std::endl;;
}
void test()
{
std::string s = "超级大的string";
test1(std::move(s));
std::cout <<"test:"<< s.c_str() << std::endl;
return;
}
int main()
{
test();
system("pause");
}
运行结果如下:
“C++ move semantic移动语义是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。