当前位置: 首页 > news >正文

C++11新增标准讲解(上)

一,{}(列表初始化)

        一切对象均可用 {} 初始化,例如下面代码,不管是自定义类型或者内置类型都可以使用{}初始化,还能将=省略。

        需要注意的是当我们使用vector<Data>时不能用{}来初始化,可以发现下图使用{}初始化时,只有年份被初始化了,其他都是使用的缺省值。

        如果需要初始化vector<Data>的话就需要使用std::initializer_list来初始化容器

class Data
{
public:Data(int y=1,int m=1,int d=1):_y(y),_m(m),_d(d){ }Data(const Data& data):_y(data._y),_m(data._m),_d(data._d){ }private:int _y;int _m;int _d;
};int main()
{Data d1 = { 2022,3,5 };//自定义类型Data d2{ 2022,3,5 };//自定义类型vector<Data> v1{ 2003,4,5 };//错误vector<Data> v2 = { 2003,4,7 };//错误vector<Data> v3 = { {2003,3,3},{2026,6,6} };//采用用隐式类型转换v3.push_back({2004,5,8});//隐式类型转return 0;
}

        可以看到push_back也可以使用隐式类型转来插入数据

二,左值和右值

        左值:能被取地址,能持久的存在,不是临时的,生命周期不是瞬间的

        右值:不能被取地址,可以认为临时对象就是右值

int main()
{//左值int a = 2;string s1("ded");int* p = new int(0);cout << &s1 << endl;//右值int b = 3;int c = 4;(b + c);//生命周期就在这一行string("hhh");//匿名对象生命周期也只有这一行cout << &(b + c) << endl;//报错,右值不能取地址return 0;
}

三,左值引用与右值引用

//左值引用
int& a1 = a;
string& ss = s1;//右值引用
string&& sss = string("hhh");
int&& bc = (b + c);

 可以看到左值引用使用一个&,而右值引用使用的是&&。

左值引用与右值引用就是给对应的对象取别名,同时右值引用还能延长对象的生命周期,而左值引用如果需要能延长对象生命周期的话就必须加const。

	const int& r1 = (b + c);//如果想用左值引用给右值取别名,需要加上constint&& r2 = move(b);//如果想用右值引用给左值取别名,需要加上move()

move()是仿函数,作用是将目标对象强制转换为右值

需要注意的是变量表达式都是左值属性,也就意味着⼀个右值被右值引用绑定后,右值引用变量变 量表达式的属性是左值,如果需要保持原来的属性就需要用到完美转发。

类型折叠:我们在将右值或者左值当实参传入函数时,会发生类型折叠

传入右值

template<class T>
void func(T&& a)//T->int
{T b = 6;//T->int
}int main()
{int a = 2, b = 4;int&& x = (a + b);func(x);//传入的是右值,原本是int&&,传入函数后会被折叠成intreturn 0;
}

传入左值

template<class T>
void func(T&& a)//T&&->int&
{T b = 6;//T->int&,会报错,因为6是右值
}int main()
{int a = 2, b = 4;int&& x = (a + b);func(a);//传入的是左值,原本是int&,传入函数后会把后面的&&折叠掉return 0;
}

还需要知道的是&与&,&&折叠之后的属性还是左值,&&只有跟&&折叠时属性才是右值

四,移动构造与移动赋值

        有了右值引用之后就出现了移动构造与移动赋值,大大减少了自定义类型传参时的拷贝

        在没有引进之前,我们如果要接收一个函数返回的局部对象时就会先拷贝生成一个临时对象,然后再将临时对象拷贝给接收的对象,这样效率不是很高。

        如果想要提高效率有两个方法,一种是将需要接收函数返回值的对象直接当函数参数,直接在函数内部改变s的值,还有一种是编译器的优化,编译器如果优化非常的好就可能将原本需要两次拷贝的直接优化成一次拷贝。

string addstring()
{string s1;//...return s1;//会拷贝成临时对象
}void addstring1(string& s)//
{//...直接对s进行操作,因为传入的是引用,里面改变了外面也会改变,就达到了减少拷贝}
int main()
{string s = string(s);return 0;
}

        在引进之后,移动构造和移动赋值的第一个参数都是右值引用的类型,他的本质是要“窃取”引用的 右值对象的资源,而不是像拷贝构造和拷贝赋值那样去拷贝资源,从提高效率。

相关文章:

  • 阿里开源千问3向量模型 超越Google与OpenAI
  • Bootstrap 3.5 框架文件结构与 API 使用指南
  • 【Linux】Linux 进程间通讯-管道
  • 新闻速递|Altair 与佐治亚理工学院签署合作备忘录,携手推动航空航天领域创新
  • 制作电子相册
  • 职业生涯思考
  • 【AI】传统导航地图和智驾地图的区别
  • 智能心理医疗助手开发实践:从技术架构到人文关怀——CangjieMagic情感医疗应用技术实践
  • Webpack的基本使用 - babel
  • 【应用】Ghost Dance:利用惯性动捕构建虚拟舞伴
  • javascript中Cookie、BOM、DOM的使用
  • 大数据量高实时性场景下订单生成的优化方案
  • 前端删除评论操作(局部更新数组)
  • 第二届智慧教育与计算机技术国际学术会议(IECT 2025)
  • 【001】frida API分类 总览
  • Tesseract配置参数详解及适用场景(PyTesseract进行OCR)
  • GAN模式奔溃的探讨论文综述(一)
  • 服务器中日志分析的作用都有哪些
  • 功率估计和功率降低方法指南(3~5)
  • LangChain【7】之工具创建和错误处理策略
  • 新网站制作怎么样/长沙seo外包优化
  • 网站开发业务怎么开展/泰州seo排名扣费
  • 现在做网站怎么赚钱/百度平台客服电话
  • wordpress限制单独站点大小/宁波网络优化seo
  • 网站建设报价清单明细/深圳搜索优化排名
  • 正规的家居行业网站开发/高端网站建设报价