初始化列表

作用:初始化列表用于初始化类的成员变量。

语法:在构造函数体之后,函数体之前进行初始化,是初始化列表,用v1对m1进行初始化,用v1和v2对m2进行初始化

    ClassName ::ClassName():m1(v1), m2(v1,v2), m3(v3)

    {

                   // do something

    }

#include <stdio.h>

class Test
{
private:
    const int a;   
const int b;
   const int c;
public: Test(): a(10),b(10),c(10) // 初始化列表 { } int getCI() { return ci; } };

 

 

注意:

  1. 成员变量的初始化只能通过初始化列表。

  1. 成员初始化顺序和成员声明顺序相同。

  2. 成员初始化列表优先于构造函数体执行。

  3. 成员的初始化顺序不依赖于成员在初始化列表中的位置。(m1, m2, m3的初始化顺序并不是从左到右依次执行,决定于成员的声明顺序)

 

类中的const成员变量:

  1. 类中的const成员会被分配空间,且分配的空间和类被分配的空间是一致的。

  2. 类中的const只能在初始化列表中被初始化。

  3. 编译器无法得到const成员的初始值,所以无非是进入符号表变成常量。

#include <stdio.h>

class Value
{
private:
    int mi;
public:
    Value(int i)
    {
        printf("i = %d\n", i);       //成员的声明顺序,所以打印的顺序为 100,2,3,1
        mi = i;
    }
    int getI()
    {
        return mi;
    }
};

class Test
{
private:
    const int ci;     // 成员的声明顺序
    Value m2;
    Value m3;
    Value m1;
public:
    Test() : m1(1), m2(2), m3(3), ci(100)    // 成员的初始化列表
    {
        printf("Test::Test()\n");     // 构造函数的函数体在初始化列表后执行,所以打印的顺序为 100,2,3,1,"Test::Test()"
    }
    int getCI()
    {
        return ci;
    }
    int setCI(int v)
    {
        int* p = const_cast<int*>(&ci);  // 通过强制类型转换将只读属性去掉
        
        *p = v;
    }
};


int main()
{
    Test t;
    
    printf("t.ci = %d\n", t.getCI());
    
    t.setCI(10);
    
    printf("t.ci = %d\n", t.getCI());
    
    return 0;
}

 

 

栈里的对象构造顺序: 取决于程序执行流。

 

堆里的对象构造顺序: 依赖于new关键字的使用顺序。

 

全局的对象构造顺序: 全局的对象构造顺序不确定,取决于编译器。

#include <stdio.h>

class Test
{
public:
    Test(const char* s)
    {
        printf("%s\n", s);
    }
};
#include "test.h"

Test t1("t1");
Test t2("t2");
Test t3("t3");
Test t4("t4");   // 全局对象构造时间在main()函数之前,但是这四个构造的顺序不确定

int main()          
{
    Test t5("t5");
}

 

posted @ 2019-04-15 20:50  张不源  Views(935)  Comments(0Edit  收藏  举报