类和对象(8)—— 构造函数初始化列表

  

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

  构造函数中调用构造函数很危险。

class A
{
public:
    A(int a)
    {
        cout << "A()..." << a << endl;
        m_a = a;
    }

    void printA()
    {
        cout << "a=" << m_a << endl;
    }
    ~A()
    {
        cout << "~A()..." << endl;
    }
private:
    int m_a;
};

class B
{
public:
    B(A &a,int b)
    {
        cout << "B(A&,int)..." << endl;
        m_a = a;//或者m_a(a);都是错的。
                //当A的对象 是B类的一个成员时,在初始化B对象的时候,
                //无法给B分配空间,因为无法初始化A类对象
        m_b = b;
    }

    void printB()
    {
        cout << "b=" << m_b << endl;
        m_a.printA();
    }
    ~B()
    {
        cout << "~B()..." << endl;
    }
private:
    int m_b;
    A m_a;
};

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

  初始化列表中的初始化顺序,与声明顺序有关,与前后赋值顺序无关。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class A
{
public:
    A(int a)
    {
        cout << "A()..." << a << endl;
        m_a = a;
    }

    void printA()
    {
        cout << "a=" << m_a << endl;
    }
    ~A()
    {
        cout << "~A()..." << endl;
    }
private:
    int m_a;
};

class B
{
public:
    B(A &a1,A &a2,int b):m_a1(a1),m_a2(a2)//初始化列表
    {
        cout << "B(A&,A&,int)..." << endl;
        m_b = b;
    }

    B(int a1, int a2, int b) :m_a1(a1), m_a2(a2)
    {
        cout << "B(int,int,int)..." << endl;
        m_b = b;
    }
    void printB()
    {
        cout << "b=" << m_b << endl;
        m_a1.printA();
        m_a2.printA();
    }
    ~B()
    {
        cout << "~B()..." << endl;
    }
private:
    int m_b;
    A m_a1;
    A m_a2;
};

void test1()
{
    A a1(10), a2(20);
    B b(a1, a2, 30);
    b.printB();
}

void test(int a1,int a2,int bb)
{
    B b(a1, a2, bb);
    b.printB();
}

int main(void)
{
    test1();
    cout << "-----------------" << endl;
    B b(10, 20, 30);
    b.printB();

    return 0;
}

屏幕输出结果:

A()...10
A()...20
B(A&,A&,int)...
b=30
a=10
a=20
~B()...
~A()...
~A()...
~A()...
~A()...
-----------------
A()...10
A()...20
B(int,int,int)...
b=30
a=10
a=20
~B()...
~A()...
~A()...
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class A
{
public:
    A(int a)
    {
        cout << "A()..." << a << endl;
        m_a = a;
    }

    void printA()
    {
        cout << "a=" << m_a << endl;
    }
    ~A()
    {
        cout << "~A()..." << endl;
    }
private:
    int m_a;
};

class B
{
public:

    B(int a1, int a2, int b):m_a1(a1), m_a2(a2)
    {
        cout << "B(int,int,int)..." << endl;
        m_b = b;
    }
    void printB()
    {
        cout << "b=" << m_b << endl;
        m_a1.printA();
        m_a2.printA();
    }
    ~B()
    {
        cout << "~B()..." << endl;
    }
private:
    int m_b;
    A m_a1;
    A m_a2;
};

void test(int a1,int a2,int bb)
{
    B b(a1, a2, bb);
    b.printB();
}

int main(void)
{
    B b(10, 20, 30);
    b.printB();

    return 0;
}

屏幕输出结果:

A()...10
A()...20
B(int,int,int)...
b=30
a=10
a=20
~B()...
~A()...
~A()...
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class A
{
public:
    A(int a)
    {
        cout << "A()..." << a << endl;
        m_a = a;
    }

    void printA()
    {
        cout << "a=" << m_a << endl;
    }
    ~A()
    {
        cout << "~A()..." << endl;
    }
private:
    int m_a;
};

class B
{
public:

    B(int a1, int a2, int b):m_a1(a1), m_a2(a2)
    {
        cout << "B(int,int,int)..." << endl;
        m_b = b;
    }
    void printB()
    {
        cout << "b=" << m_b << endl;
        m_a1.printA();
        m_a2.printA();
    }
    ~B()
    {
        cout << "~B()..." << endl;
    }
private:
    int m_b;
    A m_a2;
    A m_a1;
};

void test(int a1,int a2,int bb)
{
    B b(a1, a2, bb);
    b.printB();
}

int main(void)
{
    B b(10, 20, 30);
    b.printB();

    return 0;
}

屏幕输出结果:

A()...20
A()...10
B(int,int,int)...
b=30
a=10
a=20
~B()...
~A()...
~A()...
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class A
{
public:
    A(int a)
    {
        cout << "A()..." << a << endl;
        m_a = a;
    }

    void printA()
    {
        cout << "a=" << m_a << endl;
    }
    ~A()
    {
        cout << "~A()..." << endl;
    }
private:
    int m_a;
};

class B
{
public:

    B(int a1, int a2, int b):m_a2(a2), m_a1(a1)
    {
        cout << "B(int,int,int)..." << endl;
        m_b = b;
    }
    void printB()
    {
        cout << "b=" << m_b << endl;
        m_a1.printA();
        m_a2.printA();
    }
    ~B()
    {
        cout << "~B()..." << endl;
    }
private:
    int m_b;
    A m_a1;
    A m_a2;
};

void test(int a1,int a2,int bb)
{
    B b(a1, a2, bb);
    b.printB();
}

int main(void)
{
    B b(10, 20, 30);
    b.printB();

    return 0;
}

屏幕输出结果:

A()...10
A()...20
B(int,int,int)...
b=30
a=10
a=20
~B()...
~A()...
~A()...
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;


class ABC
{
public:
    ABC(int a, int b, int c)
    {
        cout << "ABC(int, int, int)... " << endl;
        m_a = a;
        m_b = b;
        m_c = c;
    }


    ~ABC()
    {
        cout << "~ABC() ..." << endl;
    }
private:
    int m_a;
    int m_b;
    int m_c;
};

class ABCD
{
public:
    ABCD(int a, int b, int c,int d):m_abc(a,b,c),m_d(d)
    {
        cout << "ABCD(int, int, int)... " << endl;
    }

    ABCD(ABC&abc, int d) :m_abc(abc), m_d(d)
    {
        cout << "ABCD(ABC&, int)... " << endl;
    }

    ~ABCD()
    {
        cout << "~ABCD() ..." << endl;
    }
private:
    int m_d;
    ABC m_abc;
};

class AM
{
public:
    AM(int a, int m) :m_m(m)//含有一个const对象,必须要通过成员初始化列表进行初始化
            //,因为const要在声明后马上初始化
    {
        cout << "AM(int, int, int)... " << endl;
        m_a = a;
    }

    ~AM()
    {
        cout << "~AM() ..." << endl;
    }
private:
    int m_a;
    const int m_m;
};

int main(void)
{
    ABCD abcd(1, 2, 3, 4);//法一

    ABC abc(1, 2, 3);
    ABCD abcd1(abc, 4);//法二

    AM am(22,33);

    return 0;
}
原文地址:https://www.cnblogs.com/yuehouse/p/9797512.html