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

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

同时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. C# 二进制替换第一弹 byte 数组替换

    在做通讯相关的数据操作时常常须要用到 byte[]   byte 数组替换操作.比方协义转换相关的 如今提供了几种替换的方法 /// <summary> /// 二进制数据 操作 /// ...

  2. Systemtap kernel.trace("*") events source code

    http://blog.163.com/digoal@126/blog/static/16387704020131014562216/

  3. javascript-for-loop-example--reference

    We hear a lot about loops, especially for loops. So what, in fact, are they? They’re just pieces of ...

  4. HTML及简单标签介绍

    什么是HTML: HTML 语言是一种超文本的标记语言,简单来讲就是构建一套标记符号和语法规则,将所要显示出来的文字.图象.声音等要素按照一定的标准要求排放,形成一定的标题.段落.列表等单元. 标签 ...

  5. iOS UIKit:viewController之Segues (4)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  6. 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0[已解决]

    在使用百度UEditor,不小心将Newtonsoft.Json,升级了,然后就报的一个错,说: 其他信息: 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, ...

  7. CentOS安装最新的Mysql版本

    Step1: 检测系统是否自带安装mysql # yum list installed | grep mysql Step2: 删除系统自带的mysql及其依赖命令: # yum -y remove ...

  8. JavaSE、JavaEE、JavaME三者的区别

    1. Java SE(Java Platform,Standard Edition). Java SE 以前称为 J2SE. 它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应 ...

  9. Android Cursor类的概念和用法

    http://www.2cto.com/kf/201109/103163.html 关于 Cursor 在你理解和使用 Android Cursor 的时候你必须先知道关于 Cursor 的几件事情: ...

  10. 数据库导出excel表数据

    - 执行之前 (错误) 消息 错误 0xc0202009: 数据流任务 1: SSIS 错误代码 DTS_E_OLEDBERROR.出现 OLE DB 错误.错误代码: 0x80040E37.  (S ...