C++ 构造函数的初始化列表

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

#include <iostream>

using namespace std;

class A {
    private:
        int m_a;

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

        ~A() {
            cout << "A被析构了" << endl;
        }

        void printA() {
            cout << "a = " << m_a << endl;
        }

};

class B {
    private:
        int m_b;
        A m_a1;
        A m_a2;

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

        ~B() {
            cout << "B被析构了" << endl;
        }

        void printB() {
            cout << "b = " << m_b << endl;
            m_a1.printA();
            m_a2.printA();
        }
};

int main(){
    A a1(10), a2(100);

    B b(a1, a2, 1);

    b.printB();
}
#include <iostream>

using namespace std;

class A {
public:
	//显示提供一个带参数的构造函数
	A(int a) {
		m_a = a;
		cout << "a = " << m_a << "调用了构造函数" << endl;

	}
	~A(){
		cout << "a = " << m_a << "被析构了" << endl;
	}

	void printA(){
		cout << " a = " << m_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 = " << m_b << " 调用了析构函数" << endl;
	}

private:
	int m_b;
	A m_a2;
	A m_a1;
};

int main(void) {

	B b2(30, 40, 50);
	b2.printB();

	return 0;
}

注:

  1. 类内部的对象初始化的顺序,跟对象的定义顺序一样,跟初始化列表中的顺序无关
  2. 析构的顺序就跟构造的顺序相反

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

#include <iostream>

using namespace std;

class A{
	public:
		//显示提供一个带参数的构造函数
		A(int a){
			m_a = a;
			cout << "a = " << m_a << "调用了构造函数" << endl;

		}

		~A(){
			cout << "a = " << m_a << "被析构了" << endl;
		}

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

class B{
	public:
		B(int b) :a1(10), a2(100) { //在初始化B的时候通过初始化列表给内部对象a1 和a2 进行了初始化
		
			m_b = b;
			/*
			a1(10);
			a2(20);
			*/
			cout << "b = " << m_b << "调用了构造函数" << endl;
		}

		B(int aa1, int aa2, int b) : a1(aa1), a2(aa2), m_b(b) { //通过初始化列表不仅能够初始化成员对象, 还可以初始化成员变量

		}

		void printB(){
			cout << "b = " << m_b << endl;
			a1.printA();
			a2.printA();
		}

		~B(){
			cout << "b = " << m_b << " 调用了析构函数" << endl;
		}

	private:
		int m_b;
		A a2;
		A a1;
};

//类内部的对象初始化的顺序,跟对象的定义顺序一样,跟初始化列表中的顺序无关
//析构的顺序就跟构造的顺序相反

class ABC{
	public:
		
		ABC(int a, int b, int c, int m) :m_m(m) {  // const常量只能在 初始化列表中 初始化
			cout << "ABC(int, int, int)" << endl;
			m_a = a;
			m_b = b;
			m_c = c;
			// const 常量不能在这里进行初始化操作
		}


		~ABC(){
			cout << "~ABC()" << endl;
		}

		void printABC(){
			cout << m_a << "," << m_b << "," << m_c << "," << endl;
		}

	private:
		int m_a;
		int m_b;
		int m_c;
		const int m_m; // 常量
};


class ABCD{
	public:
		ABCD(int a, int b, int c, int d, int m) :m_abc(a, b, c, m), m_d(d) {//常量成员变量不能够赋值,只能通过初始化列表进行初始化
	
			m_d = d;
		}

		ABCD(ABC&abc, int d) :m_abc(abc){
			m_d = d;
		}

	private:
		ABC m_abc;
		int m_d;
};

int main(void){

	B b(10, 20, 30);

	b.printB();

	ABC abc(10, 20, 30, 6);
	ABCD abcd(1, 2, 3, 4, 6);

	ABCD abcd1(abc, 40);

}

注:通过初始化列表不仅能够初始化成员对象, 还可以初始化成员变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值