C++在类的构造函数中,可以两种方式初始化成员数据(data member)。

1,在构造函数的实现中,初始类的成员数据。诸如:
class point
{
private:
 int x,y;
public:
 point(int m=0,int n=0)
 {
  x=m;
  y=n;
 }
 int GetX()
 {
  return x;
 }
 int GetY()
 {
  return y;
 }
};
2,还可以定义初始化成员列表(Initializer list)来初始化成员数据(data member)。
  改写构造函数如下:
 point(int m=0,int n=0):x(m),y(n)
 {
 }
这样咋一看没有什么不同,确实,对于上面的这种简单列子来说,也真的没有太大不同。
 
那我们为什么要用初始化成员列表,什么时候用初始化成员列表来初始化成员数据呢?Lippman的《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表:
 
一,需要初始化的数据成员是对象的情况;
二,需要初始化const修饰的类成员;
三,需要初始化引用成员数据;
 
现在分别举例说明:
一,需要初始化的数据成员是对象。
---------------------------
#include <stdio.h>
class point
{
protected:
 int m_x,m_y;
public:
 point(int m=0,int n=0)
 {
  m_x = m;
  m_y = n;
  printf("constructor called!/n");
 }
 point(point& p)
 {
  m_x = p.GetX();
  m_y = p.GetY();
  printf("copy constructor called!/n");
 }
 int GetX()
 {
  return m_x;
 }
 int GetY()
 {
  return m_y;
 }
};
 
class point3d
{
private:
 point m_p;
 int m_z;
public:
 point3d(point p, int k)
 {
  m_p = p;                              //这里是对m_p的赋值
  m_z=k;
 }
 point3d(int i,int j, int k):m_p(i,j)   // 相当于 point m_p(i,j)这样对m_p初始化
 {
  m_z=k;
 }
 void Print()
 {
  printf("%d,%d,%d /n",m_p.GetX(),m_p.GetY(),m_z);
 }
};
---------------------------------------
上述代码中Point3d是一个3D坐标,他有一个point的2D坐标和一个成员组成。
我们现在想定义一个3D坐标p3d,可以这样实现:
void main()
{
 point p(1,2);    //先定义一个2D坐标
 point3d p3d(p,3);
 p3d.Print();
}
从point3d实现体可以看出,我们是通过对m_p进行赋值,这样不仅调用copy constructor产生临时对象而且是对m_p的一个赋值操作。
而如果使用成员初始化列表,我们则可以这样:
void main()
{
 point p(1,2);
 point3d p3d(1,2,3);
 p3d.Print();
}
p3d中的point型成员是通过调用初始化的方式构建的。由于对象赋值比初始化要麻烦的多,因此也带来的性能上的消耗。(可以参见Scott Meyers著《effective C++》条款12)。
这也是我们在对成员数据是对象成员的采用初始化列表进行初始始化的主要原因。
 
二,需要初始化const修饰的类成员;
三,需要初始化引用成员数据;
对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用类型必须定义赋值在一起)因此只能用初始化列表对齐进行初始化。
上面两点比较好明白,可以用一个例子加以说明:
-------------------------------------
#include <stdio.h>
class base
{
private:
 const int a;
 int& b;
public:
// base(int m, int n)
// {
//  a = m;
//  b = n;
// }
 base(int m, int n):a(m),b(n)
 {}
};
 
void main()
{
 base ba(1,2);
}
---------------------------
上面红色的部分初始化的方式是不允许的通不过编译,通过初始化列表则可以很好的定义。
 

C++中成员初始化列表的使用的更多相关文章

  1. (转) C++中成员初始化列表的使用

    C++在类的构造函数中,可以两种方式初始化成员数据(data member). 1,在构造函数的实现中,初始类的成员数据.诸如: class point{private: int x,y;public ...

  2. C++中使用初始化列表的情况

    http://blog.csdn.net/iceshirley/article/details/5688696 要理解这个问题,从概念上,我们要知道一点,那就是构造函数的执行过程会分成两个阶段:隐式或 ...

  3. C++:用成员初始化列表对数据成员初始化

    1.在声明类时,对数据成员的初始化工作一般在构造函数中用赋值语句进行. 例如: class Complex{ private: double real; double imag; public: Co ...

  4. C++类的成员初始化列表的相关问题

    在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list): 1,初始化一个引用成员(reference member): 2,初始化一个常量 ...

  5. C++: 类成员初始化列表语法

      类的成员初始化列表的初始化的基本语法,类的构造函数还可以运用此语法为其变量初始化: class Class { private: int a; int b; char ch; public: Cl ...

  6. C++ 成员初始化列表

    1.什么是成员初始化列表 #include<iostream> #include<string> using namespace std; class Weapon { pri ...

  7. C++的成员初始化列表和构造函数体(以前未知)

    成员的初始化列表和构造函数在对成员指定初值方面是不一样的.成员初始化列表是对成员初始化,而构造函数,是对成员赋值 成员初始化列表使用初始化的方式来为数据成员指定初值, 而构造函数的函数体是通过赋值的方 ...

  8. c++类 用冒号初始化对象(成员初始化列表)

    c++类 用冒号初始化对象(成员初始化列表) 成员初始化的顺序不同于它们在构造函数初始化列表中的顺序,而与它们在类定义中的顺序相同 #include<iostream> ; using n ...

  9. C++ 使用成员初始化列表的一个小坑

    注意在成员列表中初始化的顺序并不是列表顺序 而是: 在类中声明的顺序! EventLoop::EventLoop() :looping(false), quit(false),_tid(curThre ...

随机推荐

  1. Numpy 利用数组进行数据处理

    Numpy数组使你可以将许多种数据处理任务表述为简洁的数组表达式(否则需要编写循环). 用数组表达式代替循环的做法,通常被称为矢量化.一般来说,矢量化数组运算要比等价的纯跑一趟湖南快 上一两个数量级( ...

  2. 【转】【Python】Python正则表达式使用指导

    1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...

  3. django学习2 视图和模板

    1 编写更多的视图 polls/views.py def detail(request, question_id): return HttpResponse("You're looking ...

  4. CentOS7使用firewalld打开关闭防火墙与端口[转]

    转自:http://www.cnblogs.com/moxiaoan/p/5683743.html1.firewalld的基本使用启动: systemctl start firewalld查看状态: ...

  5. c# 创建压缩包并下载文件

    //DLL using ICSharpCode.SharpZipLib.Core;using ICSharpCode.SharpZipLib.Zip; public void DownloadZipF ...

  6. Java非递归的方式获取目录中所有文件(包括目录)

    零.思路解析 对于给出的文件查看其下面的所有目录,将这个目录下的所有目录放入待遍历的目录集合中,每次取出该集合中的目录遍历,如果是目录再次放入该目录中进行遍历. 一.代码 /** * 非递归的方式获取 ...

  7. linux 下启动tomca慢问题

    编辑文件vim /etc/profile 后面加入一句:export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom" 设置立 ...

  8. iPhone 配置使用工具

    “iPhone 配置实用工具”可让您轻松地创建.维护和安装配置描述文件及对配置描述文件进行加密,跟踪和安装预置描述文件与授权的应用程序,以及采集包括控制台日志在内的设备信息. http://suppo ...

  9. cocos2d - CCSprite各种动画

    转自 ITeye技术网站 // 触摸屏 -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { for( UITouc ...

  10. useradd groupadd passwd usermod userdel chfn id

    chfn   修改用户信息 id 显示当前用户和用户组的id