解决关于initializer_list对象拷贝的疑问
2016-07-22 16:03
316 查看
C++Primer P198 上说拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,拷贝后,原始列表和副本共享元素。
起初有几个疑问:
①一个是不会拷贝列表中的元素是什么意思,那下面的拷贝操作有什么用?
②另一个不会拷贝列表中的元素那又怎么个共享法?
在上面添加一个for循环把ilst的值打印出来
运行上面的程序发现,结果是这样的:
③那又产生一个疑问,initializer_list对象的元素永远是常量,那为什么又能改变ilst的内容呢?
琢磨了一下,发现我忽略了一个重要的点,那就是initializer_list对象的本质,书上是这么说的:initializer_list是一种标准库类型,用于表示某种特定类型的值的数组。重要的就是这句话,所以initializer_list对象本质上就是数组。而当我们使用数组的对象时,使用的其实是一个指向数组首元素的一个指针, 这句话也很重要,我们又通常用某个地址来表示从这个地址开始的大小不同的比特串,所以我们通常用数组首元素的地址来表示该数组的内存地址,所以上面的拷贝操作,拷贝的实际上是一个指针指向的内存地址,把ilst2所指向的内存地址拷贝给ilst,从而使得ilst指向ilst2指向的那个内存地址,而这里的ilst2指向的是系统用于存放上面初始化ilst2时所用的常量的一个临时内存地址。
运行结果:
ilst和ilst2指向了同一个内存地址。
分析到这里,三个问题也就都解决了。
一、initializer_list对象在执行拷贝操作时拷贝的实际上是一个内存地址,所以当然不会拷贝列表中的元素。
二、既然拷贝后,原始initializer_list对象和副本指向的是同一个内存地址,所以可以说是共享元素。
三、上面的赋值操作只是改变了指针所指的内存地址,并没有改变ilst原来所指内存地址上面的值,这就有点像指向常量的指针和常量指针这两种指针的区别。
起初有几个疑问:
①一个是不会拷贝列表中的元素是什么意思,那下面的拷贝操作有什么用?
std::initializer_list<int> ilst = {1,2,6}; std::initializer_list<int> ilst2 = { 1,2,3,4,5 }; ilst = ilst2;
②另一个不会拷贝列表中的元素那又怎么个共享法?
在上面添加一个for循环把ilst的值打印出来
for (auto beg = ilst.begin(); beg != ilst.end(); ++beg) { std::cout << *beg << std::endl; }
运行上面的程序发现,结果是这样的:
③那又产生一个疑问,initializer_list对象的元素永远是常量,那为什么又能改变ilst的内容呢?
琢磨了一下,发现我忽略了一个重要的点,那就是initializer_list对象的本质,书上是这么说的:initializer_list是一种标准库类型,用于表示某种特定类型的值的数组。重要的就是这句话,所以initializer_list对象本质上就是数组。而当我们使用数组的对象时,使用的其实是一个指向数组首元素的一个指针, 这句话也很重要,我们又通常用某个地址来表示从这个地址开始的大小不同的比特串,所以我们通常用数组首元素的地址来表示该数组的内存地址,所以上面的拷贝操作,拷贝的实际上是一个指针指向的内存地址,把ilst2所指向的内存地址拷贝给ilst,从而使得ilst指向ilst2指向的那个内存地址,而这里的ilst2指向的是系统用于存放上面初始化ilst2时所用的常量的一个临时内存地址。
std::initializer_list<int> ilst = {1,2,6}; std::initializer_list<int> ilst2 = { 1,2,3,4,5 }; std::cout << ilst.begin() << " " << ilst2.begin() << std::endl; ilst = ilst2; std::cout << ilst.begin() << " " << ilst2.begin() << std::endl;
运行结果:
ilst和ilst2指向了同一个内存地址。
分析到这里,三个问题也就都解决了。
一、initializer_list对象在执行拷贝操作时拷贝的实际上是一个内存地址,所以当然不会拷贝列表中的元素。
二、既然拷贝后,原始initializer_list对象和副本指向的是同一个内存地址,所以可以说是共享元素。
三、上面的赋值操作只是改变了指针所指的内存地址,并没有改变ilst原来所指内存地址上面的值,这就有点像指向常量的指针和常量指针这两种指针的区别。
相关文章推荐
- C++ stringstream的用法
- Canvas 学习之 (4) rotate
- 使用Nuwa实现Android热修复
- noip 2004-合唱队形-dp
- 工作框架各种使用整理---服务状态变更数据
- 一个程序员的进化史-第十章
- [GIF] GIF Loop Coder - Animation Functions
- 前端与服务器分离开发出现跨域问题,jsonp与gulp-connect注意点,angularjs改造
- 外部主机不允许连接Mysql设置的解决
- mysql5.7 xtarbackup2.4.1使用(附带脚本)
- SolrCloud+zookeeper
- 字符串的排列组合
- 旋转动画
- DAY9:leetcode #19 Remove Nth Node From End of List
- LeetCode 223. Rectangle Area
- python jinja2配置模板
- redis适用场景
- 一个不错的cef的封装
- leetcode_c++:栈:Evaluate Reverse Polish Notation(150)
- spart快速大数据分析学习提纲(一)