c++中初始化列表简单记录

首先 放另外一个博主的链接:http://www.cnblogs.com/graphics/archive/2010/07/04/1770900.html

在学习c++构造函数的过程中遇到了初始化列表这个词,便主动搜索资料,学习初始化列表这个概念

一、初始化列表的由来

在构造函数中,除了 函数名,函数体外,可以有初始化列表,也可以没有初始化列表,初始化列表不是必须的。

struct  Test

{

  public:

   Test(string   n, int b): name(n), id(b){};//初始化列表的表现形式 :初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段

  // Test(string   n, int b)

  // {
  //  name = n;

  //  id     = b;

  //} 一般的构造函数

  private:

  string name;

  int id;

};

在构造函数中,构造函数分两步给成员变量赋值,第一是初始化阶段,第二是计算阶段,并且初始化阶段在前,计算阶段在后。

初始化阶段:

所有类类型(class type)的成员都会在初始化阶段初始化,即使该成员没有出现在构造函数的初始化列表中。意思需初始化的成员没有在初始化列表中,就会调用相应的构造函数来进行初始化,如默认构造函数,一般带参构造函数,复制构造函数,类型转换构造函数等。

计算阶段:

一般用于执行构造函数体内的赋值操作

我理解的赋值操作就是构造函数中函数体内部的操作,

struct Test1 {

  Test1() // 无参构造函数

   {         cout << "Construct Test1" << endl ;

    }

Test1(const Test1& t1) // 拷贝构造函数

   {         cout << "Copy constructor for Test1" << endl ;

            this->a = t1.a ;

    }

Test1& operator = (const Test1& t1) // 赋值运算符

{

         cout << "assignment for Test1" << endl ;

     this->a = t1.a ;

   return *this;

}

int a ;

};

struct Test2 {

   Test1 test1 ;          //成员变量

   Test2(Test1 &t1)    //构造函数

    {         test1 = t1 ;

     }

};

执行代码:

Test1 t1; // 会调用Test1 的默认构造函数,打印 Construct Test1

Test2(t1); //打印Construct Test1:因为 Test2 中有 test1 的成员变量,在它的初始化阶段 会调用Test1 默认的构造函数,

// 打印  assignment for Test1 , 是在调用Test2的构造函数阶段, 赋值操作,用到的是=号的重载。

二、成员变量如何初始化

1、用初始化列表初始化, 初始化列表是用来初始化成员变量的。

2、在构造函数中,用赋值语句进行初始化。

三、初始化列表有什么好处

使用初始化列表主要是基于性能问题,使用初始化列表少了一次调用默认构造函数的过程,当成员变量多的时候,这样比较快。快才是硬道嘛。

struct Test2
{
    Test1 test1 ;
    Test2(Test1 &t1):test1(t1){}
}

这样写的话,Test2的初始化列表,直接调用拷贝构造函数初始化test1,就不会调用Test1 的默认构造函数了。 这样效率更高。

四、那些必须使用初始化列表初始化

1、常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面

2、引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面。

3、没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。

注:没有默认构造函数的类的类型如果不用初始化列表来初始化就会调用默认的构造函数,但是它又没有默认的构造函数,就会报错。----billadd

大牛总结:

1. 如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数, 而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数, 如果没有初始化列表,那么他将无法完成第一步,就会报错。

2、类成员中若有const修饰,必须在对象初始化的时候,给const int m 赋值 当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化, 因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。

举例:

struct Test2
{
    Test1 test1;

  Test1 &aaa;
    const int m;
    Test2(Test1 &t1):test1(t1), m(10),aaa(test1){}
};

五、类中变量初始化的顺序

成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的

struct foo
{
    int i ;
    int j ;
    foo(int x):i(x), j(i){}; // ok, 先初始化i,后初始化j
};

个人总结:

1、构造函数中可以有初始化列表,也可以没有初始化列表

2、构造函数分为初始化和计算两个阶段,初始化阶段在前,计算阶段在后。

3、用初始化列表初始化变量比一般的赋值函数快,因为省去了调用默认构造函数。

4、常量变量、引用、无默认构造函数的类,必须用初始化列表初始化。

5、初始化列表的顺序,是根据在类中出现的顺序初始化的。

备注:dm10_init_list.cpp

时间: 2024-10-09 00:08:22

c++中初始化列表简单记录的相关文章

c++中初始化列表的初始化变量顺序问题

例题来看:请问下面程序打印出的结果是什么? 1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class base 7 { 8 private: 9 int m_i; 10 int m_j; 11 public: 12 base(int i):m_j(i),m_i(m_j); 13 base():m_j(0),m_i(m_j){} 14 int get_i() {return m_i;} 1

spring中的JdbcTemplate简单记录

JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句: update方法及batchUpdate方法:update方法用于执行新增.修改.删除等语句:batchUpdate方法用于执行批处理相关语句: query方法及queryForXXX方法:用于执行查询相关语句: call方法:用于执行存储过程.函数相关语句. JdbcTemplate类支持的回调类: 预编译语句及存储过程创建回调:用于根据JdbcTemplate提供的连接创

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

在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list): 1,初始化一个引用成员(reference member): 2,初始化一个常量对象(const member); 3,调用一个基类的构造函数,且该基类的构造函数有一组参数: 4,调用一个成员类(member class)的构造函数,且该构造函数有一组参数 这四种情况程序可以正常编译,但是效率有所欠缺(下面会具体说到). class Word{ String _name; in

[C++11笔记001]修改通用库中的XDynamicArray,使它可以支持C++11的初始化列表和for循环

今天,有空翻了一下<C++Primer plus(第六版)>,看到里面有介绍新的for循环和初始化列表,但是我实现的动态数组XDynamicArray不支持这些新特性,没办法,只好进行改造了. 首先是for循环,如下面的样式 for(auto e:stList) { cout<<e<<endl; } 是于就各种google,和查找C++11的array的源代码,总结:就是提供一个标准的iterator和begin,end这两个方法,就可以了. 是于定义了一个iterat

只能在初始化列表中初始化的变量

1.const变量 有几个容易混淆的地方: (1)const 的变量只能通过构造函数的初始化列表进行初始化:(貌似在c++11中可以正常编译) (2)static 的变量只能通过在类外重新定义进行初始化: (3)static const 变量 只能通过在类中直接用”=”进行赋值. 2.引用 引用只能初始化,不能赋值 3.不含默认构造函数的类的对象 因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化. 构造函数的函数体内只能做赋值而不是初始化,因此初始化const对

什么时候需要在类的构造函数中使用初始化列表

1,如果基类没有default构造函数,则意味着其不能自己初始化.如果其被派生,派生类的构造函数要负责调用基类的构造函数,并传递给它需要的参数.下例中Base 2,如果类成员没有默认构造函数.下例中Elem4 2,如果类的成员变量中含有const成员变量,如果不使用列表,在构造函数中是不能对其赋值的,会导致编译失败.下例中b 3,如果类的成员变量中含有引用,引用必须被初始化.下例中c 4,需要提高效率的时候,如果不使用初始化列表,而放在构造函数体内赋值的方法,则变量先被默认构造函数初始化,然后又

C++初始化列表和大括号中构造的差别

C++的对象构造函数有两种初始化的方法: 1.初始化列表 2.大括号中面赋值 这两种推荐使用另外一种.原因在于使用初始化列表仅仅须要进行一次初始化.而使用大括号内赋值的话首先须要调用默认构造函数初始化,然后再进行赋值,效率上明显前者更优.

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

http://blog.csdn.net/iceshirley/article/details/5688696 要理解这个问题,从概念上,我们要知道一点,那就是构造函数的执行过程会分成两个阶段:隐式或显示的初始化阶段以及一般的计算阶段.计 算阶段由构造函数体内的所有语句组成,在计算阶段,数据成员的设置被认为是赋值,而不是初始化. 而初始化是显式的还是隐式的,取决于是否存在初始化函数列表.隐式初始化阶段按照声明的顺序依次调用素有基类的缺省构造函数,然后是所有成员类对象的缺省构造函数. 现在我们回归

SharePoint中删除列表记录

方法1(快速,以理解,可以封装): SPList spListQuestion = spWeb.Lists["Question List"]; for (int i = spListQuestion.Items.Count - 1; i >= 0; i--) { spListQuestion.Items[i].Delete(); } 方法2(繁琐): SPList spListQuestion = spWeb.Lists["Question List"]; s