大家请看下面的代码,请问 输出结果是??

/**
* @file vector-destroy.cc
* @brief an interesting problem regarding vector
* @author shoulinjun@126.com
* @version 0.1.00
* @date 2014-03-16
*/ #include <iostream>
#include <vector>
using namespace std; class MyClass
{
public:
MyClass(int x=0)
: val(x) {} ~MyClass() {
cout << val << " ";
}
void set_val(int x){
val = x;
}
private:
int val;
}; int main(void)
{
vector<MyClass> vec(5); for(vector<MyClass>::size_type i=0; i!=vec.size(); ++i)
vec[i].set_val(i); return 0;
}

我定义了一个 MyClass 的类,这个类的析构函数中,会输出类的成员变量 val 的值。

在 main 函数中,我定义了一个5个元素的 vector,并把这些类的 val 依次设置为 0 1 2 3 4

然而结果是

从结果可以发现两点有意思的:

1. vector 的析构函数调用时, 按照顺序依次调用 vector中的对象的析构函数

2. 为什么会出现两个 0 呢???

不是仅仅定义了 5 个 Myclass 的对象吗??为什么析构函数调用了 6 次??

通过对 STL 源码的分析,终于明白为什么了。。

vector 的构造函数如下:

explicit vector(size_type n) {
fill_initialize(n, T());
}

T() 建立了一个临时对象, fill_initialize() 调用 T 的复制构造函数初始化所有的数组元素。

这个临时对象就是导致我们的结果出现两个 0 的罪魁祸首。

再简要地提几点:

1. C++ 一定会合成一个默认的类的复制构造函数, 无论你是否定义了一个复制构造函数

2. vector 中的元素必须得拥有复制构造函数。

C++ Primer----一个关于 vector 的有趣的问题的更多相关文章

  1. C++ Primer : 第九章 : vector变长、string的其他操作以及容器适配器

    vector变长机制.string的其他构造方法,添加.替换和搜索操作,string比较和数值转换,最后是容器适配器. vector对象是如何增长的 vector和string类型提供了一些成员函数, ...

  2. C++中一个函数隐藏的有趣例子

    函数隐藏是一个函数的定义或声明导致其他一些函数不可见. 函数A隐藏函数B的条件:      1. 两个函数具有相同的函数名称      2. 具有不同的作用域.所谓定义域函数定义或声明的位置,如全局作 ...

  3. 发现一个c++ vector sort的bug

    在开发中遇到一个非常诡异的问题:我用vector存储了一组数据,然后调用sort方法,利用自定义的排序函数进行排序,但是一直都会段错误,在排序函数中打印参加排序的值,发现有空值,而且每次都跟同一个数据 ...

  4. [转载]Vector用法(C++ Primer中文版)

    转自:http://blog.sciencenet.cn/blog-261330-551086.html vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.和 string 对 ...

  5. 把《c++ primer》读薄(3-2 标准库vector容器+迭代器初探)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 标准库vector类型初探,同一种类型的对象的集合(类似数组),是一个类模版而不是数据类型,学名容器,负责管理 和 存储的元素 ...

  6. C++ Primer 有感(标准库vector及迭代器)

    vector是同一种对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库将负责管理与存储元素相关的类存.引入头文件 #include<vector> 1.vecto ...

  7. Cocos2d-x3.0模版容器之中的一个:cocos2d::Vector&lt;T&gt;

    版本号:v3.0 beta以后 语言:C++ 定义在 "COCOS2DX_ROOT/cocos/base" 路径下的 "CCVector.h" 的头文件里. t ...

  8. c++转载系列 std::vector模板库用法介绍

    来源:http://blog.csdn.net/phoebin/article/details/3864590 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作 ...

  9. C++Primer 5th 练习 12.19

    这阵子真是太忙了, 连续做了四个课设. 当然这并不能作为好久没写博客的借口, 没写博客的主要原因只有一个: 懒. 最近又开始回顾C++的语法与特性(据说C++就是一门需要反复回顾的语言),以及学习C+ ...

随机推荐

  1. python 练习 4

    #!/usr/bin/python # -*- coding: utf-8 -*- from math import sqrt import random def daoxu(n): d=n s=0 ...

  2. WAMP 403 Forbidden禁止访问 的解决办法

    修改httpd.conf文件 # onlineoffline tag - don't remove Require local To # onlineoffline tag - don't remov ...

  3. listbox鼠标拖动数据和为button注册快捷键

    将listbox1中的数据用鼠标拖动至listbox2,即有左至右. 分别对应控件注册如下事件DragEnter,MouseDown,DragDrop 代码如下: //P128 DataGridVie ...

  4. Populating Next Right Pointers in Each Node II [Leetcode]

    Problem Description http://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ ...

  5. struts2视频学习笔记 29-30(Struts 2常用标签,防止表单重复提交)

    课时28 Struts 2常用标签解说 property标签 property标签用于输出指定值: <s:set name="name" value="'kk'&q ...

  6. ocument的createDocumentFragment()方法

    在<javascript高级程序设计>一书的6.3.5:创建和操作节点一节中,介绍了几种动态创建html节点的方法,其中有以下几种常见方法: · crateAttribute(name): ...

  7. JQuery时间轴timeline插件的学习-Lateral On-Scroll Sliding with jQuery+technotarek / timeliner

    一.Lateral On-Scroll Sliding with jQuery的使用 View demo      Download source 1. HTML结构 <div id=" ...

  8. 发送广播BroadcastReceiver

    import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.vi ...

  9. 如何在 Ubuntu 15.04 系统中安装 Logwatch

    大家好,今天我们会讲述在 Ubuntu 15.04 操作系统上如何安装 Logwatch 软件,它也可以在各种 Linux 系统和类 Unix 系统上安装.Logwatch 是一款可定制的日志分析和日 ...

  10. 解析网络json数据,模拟美团界面显示。

    <?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android=&q ...