类成员的默认初始化顺序是按照声明顺序进行, 如果使用初始化列表初始化成员变量, 则必须按照成员变量的声明顺序进行;

否则, 在变量之间交替赋值时, 会产生, 未初始化的变量去赋值其他变量;

同时GCC, 也会发出警告, 如: 'class::m_xxx' will be initialized after [-Wreorder]

请看下面的代码:

template<class t>
class array {
public:
  array(int lowbound, int highbound);
  ...

private:
  vector<t> data;               // 数组数据存储在vector对象中
                                // 关于vector模板参见条款49

size_t size;                  // 数组中元素的数量

int lbound, hbound;           // 下限,上限
};

template<class t>
array<t>::array(int lowbound, int highbound)
: size(highbound - lowbound + 1),
  lbound(lowbound), hbound(highbound),
  data(size)
{

}

里面有个严重的错误,绝对没人会知道data里会有多少个元素。你也许认为在data之前size已经被初始化了,实则不然,类成员变量的初始化不是按照初始化表的顺序被初始化的,而是按照在类中声明的顺序被初始化的。

为什么会这样呢?我们知道,对一个对象的所有成员来说,它们的析构函数被调用的顺序总是和它们在构造函数里被创建的顺序相反。那么,如果允许上面的情况(即,成员按它们在初始化列表上出现的顺序被初始化)发生,编译器就要为每一个对象跟踪其成员初始化的顺序,以保证它们的析构函数以正确的顺序被调用。这会带来昂贵的开销。所以,为了避免这一开销,同一种类型的所有对象在创建(构造)和摧毁(析构)过程中对成员的处理顺序都是相同的,而不管成员在初始化列表中的顺序如何。

注意:上述内容不适用于static变量,static变量应该在类的构造函数前被初始化。

记住:初始化列表中成员列出的顺序和成员在类内声明的顺序一致。

using namespace std;  

class base {
private:
int m_i;
int m_j;
public:
base(int i) : m_j(i), m_i(m_j) {}
base() : m_j(), m_i(m_j) {}
int get_i() { return m_i; }
int get_j() { return m_j; }
}; int main () {
base obj();
std::cout << obj.get_i() << std::endl
<< obj.get_j() << std::endl;
return ;
}

输出:-858993460 98 。

Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同的更多相关文章

  1. Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  2. Effective STL 学习笔记:19 ~ 20

    Effective STL 学习笔记:19 ~ 20 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  3. python学习笔记整理——列表

    Python 文档学习笔记 数据结构--列表 列表的方法 添加 list.append(x) 添加元素 添加一个元素到列表的末尾:相当于a[len(a):] = [x] list.extend(L) ...

  4. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  5. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  6. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  7. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  8. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  9. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

随机推荐

  1. Shell编程速查手册

    https://blog.atime.me/note/shell-scripting-summary.html 总结一下日常Shell脚本里常用的知识,忘记时方便查阅. 常见的shell 常见的Lin ...

  2. [转] Python特殊语法:filter、map、reduce、lambda

    Python内置了一些非常有趣但非常有用的函数,充分体现了Python的语言魅力! filter(function, sequence):对sequence中的item依次执行function(ite ...

  3. [转] SSH 密钥认证机制

    使用 RSA 密钥对进行 SSH 登录验证 使用 RSA 密钥对验证 SSH 的优点是 1) 不用打密码 2) 比密码验证更安全:缺点是 1) 第一次配置的时候有点麻烦 2) 私钥需要小心保存.Any ...

  4. Struts2 ValueStack

    一.作用 可以作为一个数据中转站,用在前台和后台数据传递 二.生命周期 ValueStack的生命周期是随着request的创建而创建,随request的销毁而销毁. 三.结构 OgnlValueSt ...

  5. iOS Sqlite3 Demo 及 FMDB Demo

    本文是主要实现了三个函数: testSQLite3 是测试系统自带的sqlite3的demo testFMDB是测试FMDB存取简单的数据类型的 的demo testFMDB2是将任意对象作为一个整体 ...

  6. C#压缩文件为zip格式

    Vercher   C#压缩文件为zip格式 需要ICSharpCode.SharpZipLib.dll,网上下载的到. 代码是从网上找来的: 1 public class ZipClass 2 { ...

  7. Iterator<Entry<String,String>> iter=map.entrySet().iterator(); 是什么意思

    //获得map的迭代器,用作遍历map中的每一个键值对Iterator是迭代器,map之前应该定义过,姑且认为是HashMap.<Entry<String,String>>表示 ...

  8. struts_ognl详解

  9. 总结Widows 7 Start->Run 命令

    Widows + R基本上成为很常用的方式,那么通过Windows + R我们可以在运行中做什么手脚呢. 下面从最基本的系统命令说起 notepad--------打开记事本    services. ...

  10. ARM架构下linux设备树加载的方法

    引入设备树后bootloader加载DTB方法: 1. 标准方法 将linux kernel放到内存地址为<kernel img addr>的内存中. 将DTB放到地址为<dtb a ...