怎样建立一个自己的网站免费,网站建设公司品牌,湖南省郴州市邮编,网站开发需求范本本节介绍c的移动语义与新特性std::move#xff0c;本节介绍的内容主要用在性能优化上。
c移动语义和c左值右值的内容相关联#xff0c;可以先看之前发的左值右值内容。
不使用移动语义的代码如下#xff1a;
#include iostream
class String
{
public:String() …本节介绍c的移动语义与新特性std::move本节介绍的内容主要用在性能优化上。
c移动语义和c左值右值的内容相关联可以先看之前发的左值右值内容。
不使用移动语义的代码如下
#include iostream
class String
{
public:String() default;String(const char* date){std::cout Created!\n;m_Data new char[strlen(date)1];m_Size strlen(date);memcpy(m_Data, date, m_Size1);}String(const String other){std::cout Copityed!\n;m_Data new char[other.m_Size 1]; //需要在堆上分配所以会影响性能移动语义可以不在堆上进行分配m_Size other.m_Size;memcpy(m_Data, other.m_Data, m_Size 1);}~String(){delete[] m_Data;}void PrintString(){for (int i 0; i m_Size; i){std::cout m_Data[i];}std::cout \n;}
private:char* m_Data;uint32_t m_Size;
};
class Entity
{
public:Entity(const String name):m_Name(name){}void Print(){m_Name.PrintString();}
private:String m_Name;
};int main()
{Entity entity(String(pcop));entity.Print();std::cin.get();
}
上述代码执行结果如下
Created! Copityed! pcop
可以看到执行了两次内存分配一次是在Created中一次是在Copityed中因为String(pcop)先创建了一个String对象然后通过引用的方式传递给EntityEntity调用复制构造函数在复制构造函数中新建一个String对象m_Data。
使用移动语义可以减去String(pcop)创建String对象这一次内存分配代码如下
#include iostream
class String
{
public:String() default;String(const char* date){std::cout Created!\n;m_Data new char[strlen(date)1];m_Size strlen(date);memcpy(m_Data, date, m_Size1);}String(const String other){std::cout Copityed!\n;m_Data new char[other.m_Size 1]; //需要在堆上分配所以会影响性能移动语义可以不在堆上进行分配m_Size other.m_Size;memcpy(m_Data, other.m_Data, m_Size 1);}String(String other) noexcept //传递的是一个右值临时值{std::cout Moved!\n;m_Data other.m_Data; //实际进行了一次浅拷贝m_Data指针指向other.m_Data所指的内存地址m_Size other.m_Size;other.m_Size 0;other.m_Data nullptr;}~String(){std::cout Destroyed!\n;delete[] m_Data;}void PrintString(){for (int i 0; i m_Size; i){std::cout m_Data[i];}std::cout \n;}
private:char* m_Data;uint32_t m_Size;
};
class Entity
{
public:Entity(const String name):m_Name(name){}Entity(String name):m_Name((String)name) {}void Print(){m_Name.PrintString();}
private:String m_Name;
};int main()
{Entity entity(String(pcop));entity.Print();std::cin.get();
}
std::move的使用方式及移动赋值运算符代码如下
#include iostream
class String
{
public:String() default;String(const char* date){std::cout Created!\n;m_Data new char[strlen(date)1];m_Size strlen(date);memcpy(m_Data, date, m_Size1);}String(const String other){std::cout Copityed!\n;m_Data new char[other.m_Size 1]; //需要在堆上分配所以会影响性能移动语义可以不在堆上进行分配m_Size other.m_Size;memcpy(m_Data, other.m_Data, m_Size 1);}String(String other) noexcept //传递的是一个右值临时值{std::cout Moved!\n;m_Data other.m_Data; //实际进行了一次浅拷贝m_Data指针指向other.m_Data所指的内存地址m_Size other.m_Size;other.m_Size 0;other.m_Data nullptr;}String operator(String other) noexcept{std::cout Moved!\n;if (this ! other){delete[] m_Data;m_Data other.m_Data; //实际进行了一次浅拷贝m_Data指针指向other.m_Data所指的内存地址m_Size other.m_Size;other.m_Size 0;other.m_Data nullptr;}return *this;}~String(){std::cout Destroyed!\n;delete[] m_Data;}void PrintString(){for (int i 0; i m_Size; i){std::cout m_Data[i];}std::cout \n;}
private:char* m_Data;uint32_t m_Size;
};
class Entity
{
public:Entity(const String name):m_Name(name){}Entity(String name):m_Name(std::move(name)) {}void Print(){m_Name.PrintString();}
private:String m_Name;
};int main()
{//Entity entity(String(pcop));//entity.Print();String s1 pcop;//String s2 std::move(s1); //使用move将s1转换成临时变量此时调用的是构造函数而不是移动赋值运算符String s3;s3 std::move(s1); //此时调用的是移动赋值运算符s3.PrintString();std::cin.get();
}