对象的初始化列表const变量的初始化

当B类中有A类并且A类还有自己的有参数构造函数的时候,那这时若是B再使用默认构造函数就不能使用了,因为B不能对A进行初始化;

#include <iostream>
using namespace std;



class  A
{
public:
	A(int _a)
	{
		a = _a;	
	}
protected:
private:
	int a;
};
class B
{
public:
protected:
private:
	int b1;;
	int b2;
	A a1;
	A a2;

};
int main()
{
	A a1(10);
	B objB;	  //在调用objB的时候没有机会调用A的初始化函数,给A中的变量分配内存所以不能使用
	
	cout << "hello world!" << endl;
	system("pause");
    return 0;
}

解决办法:使用对象初始化列表

#include <iostream>
using namespace std;



class  A
{
public:
	A(int _a)
	{
		a = _a;	
		cout << "构造函数a = " << a<<endl;
	}
	~A( )
	{
		cout <<"析构函数a" << endl;
	}
protected:
private:
	int a;
};
//构造函数的初始化列表,解决了在B类中 组合了一个其他类的对象(A类)  A中使用了有参数构造函数
//根据构造函数的调用规则 设计了A的构造函数 就必须使用A的构造函数 但是没有机会使用 A的构造函数
//这时 构造函数额的初始化列表就排上用场
class B
{
public:
	B(int _b1,int _b2): a1(1),a2(2)	  //构造函数的初始化列表
	{
		
	}
	//参数传递
	B(int _b1,int _b2,int m,int n): a1(m),a2(n)	  //构造函数的初始化列表
	{
		  b1 =_b1;
		  b2 =_b2;
		  cout << "B的构造函数" << endl;
	}
	~B()
	{
		 cout <<"这是B的析构函数" << endl;
	}
protected:
private:
	int b1;
	int b2;
	A a2;	   //把a2放到上面是为了测试 被组合对象构造函数的调用顺序是跟定义的顺序相关 而不是列表初始化的顺序
	A a1;    //A类已经有定义的有参构造函数   若B中使用 就要使用 初始化列表
	

};
void display()
{
			  B objB1(1,2,3,4);
}
//首先在执行被组合对象的构造函数  
//如果被组合对象有多个 按照被组合对象定义的顺序 而不是按照 初始化列表的顺序、

//析构函数和构造函数的调用顺序相反
int main()
{
//	A a1(10);
//	B objB(1,2);	  //在调用objB的时候没有机会调用A的初始化函数,给A中的变量分配内存所以不能使用
	   display();
	cout << "hello world!" << endl;
	system("pause");
    return 0;
}

执行的结果:
这里写图片描述
从结果上可以看出被组合对象,构造函数的调用的顺序是和定义的顺序相关而不是初始化列表初始化的顺序;

当一个类中有 const类型的变量的时候 要使用初始化列表进行初始化

#include <iostream>
using namespace std;



class  A
{
public:
	A(int _a)
	{
		a = _a;	
		cout << "构造函数a = " << a<<endl;
	}
	~A( )
	{
		cout <<"析构函数a" << endl;
	}
protected:
private:
	int a;
};
//构造函数的初始化列表,解决了在B类中 组合了一个其他类的对象(A类)  A中使用了有参数构造函数
//根据构造函数的调用规则 设计了A的构造函数 就必须使用A的构造函数 但是没有机会使用 A的构造函数
//这时 构造函数额的初始化列表就排上用场
//初始化 列表用来给const 类型变量初始化 
class B
{
public:
	B(int _b1,int _b2): a1(1),a2(2),c(0)	  //构造函数的初始化列表
	{
		
	}
	//参数传递
	B(int _b1,int _b2,int m,int n): a1(m),a2(n),c(0)	  //构造函数的初始化列表	 const 类型变量必须在 初始化成
	{
		  b1 =_b1;
		  b2 =_b2;
		  cout << "B的构造函数" << endl;
	}
	~B()
	{
		 cout <<"这是B的析构函数" << endl;
	}
protected:
private:
	int b1;
	int b2;
	A a2;	   //把a2放到上面是为了测试 被组合对象构造函数的调用顺序是跟定义的顺序相关 而不是列表初始化的顺序
	A a1;    //A类已经有定义的有参构造函数   若B中使用 就要使用 初始化列表
	
	const int c;	  //如果类的成员中有const 类型的成员变量则必须在 初始化了,列表中进行初始化

};
void display()
{
			  B objB1(1,2,3,4);
}
//首先在执行被组合对象的构造函数  
//如果被组合对象有多个 按照被组合对象定义的顺序 而不是按照 初始化列表的顺序、

//析构函数和构造函数的调用顺序相反
int main()
{
//	A a1(10);
//	B objB(1,2);	  //在调用objB的时候没有机会调用A的初始化函数,给A中的变量分配内存所以不能使用
	   display();
	cout << "hello world!" << endl;
	system("pause");
    return 0;
}

综合

//对象做函数参数
//1 研究拷贝构造 
//2 研究构造函数,析构函数的调用顺序

//总结 构造和析构的调用顺序

#include <iostream>
using namespace std;

class ABCD 
{
public:
	ABCD(int a, int b, int c)
	{
		this->a = a;
		this->b = b;
		this->c = c;
		printf("ABCD() construct, a:%d,b:%d,c:%d  \n", this->a, this->b, this->c);
	}
	~ABCD()
	{
		printf("~ABCD() construct,a:%d,b:%d,c:%d  \n", this->a, this->b, this->c);
	}
	int getA() 
	{
		return this->a;
	}
protected:
private:
	int a;
	int b;
	int c;
};


class MyE
{
public:
	MyE():abcd1(1,2,3),abcd2(4,5,6),m(100)
	{
		cout<<"MyD()"<<endl;
	}
	~MyE()
	{
		cout<<"~MyD()"<<endl;
	}
	MyE(const MyE & obj):abcd1(7,8,9),abcd2(10,11,12),m(100)			  //在拷贝构造函数中也要有初始化列表
	{
		printf("MyD(const MyD & obj)\n");
	}

protected:
	//private:
public:
	ABCD abcd1; //c++编译器不知道如何构造abc1
	ABCD abcd2;
	const int m;	  //常量要在初始化列表中进行初始化

};

int doThing(MyE mye1)  //在调用函数的时候也会调用 copy构造函数
{
	printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());	//这种情况下是一个类中有另一个类的变量
	return 0;
}

int run2()
{
	MyE myE;
	doThing(myE);
	return 0;
}

//
int run3()
{
	printf("run3 start..\n");

	//ABCD(400, 500, 600); //临时对象的生命周期  

	ABCD abcd = ABCD(100, 200, 300);
	//若直接调用构造函数呢?
	//想调用构造函数对abc对象进行再复制,可以吗?
	//在构造函数里面调用另外一个构造函数,会有什么结果?

	printf("run3 end\n");
	return 0;
}

int main()
{
	run2();
	run3();
	system("pause");
	return 0;
}


结果:

“demotest.exe”: 已加载“E:\VS2008\demotest\Debug\demotest.exe”,已加载符号。
“demotest.exe”: 已加载“C:\Windows\SysWOW64\ntdll.dll”
“demotest.exe”: 已加载“C:\Windows\SysWOW64\kernel32.dll”
“demotest.exe”: 已加载“C:\Windows\SysWOW64\KernelBase.dll”
“demotest.exe”: 已加载“C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.21022.8_none_96748342450f6aa2\msvcp90d.dll”,已加载符号。
“demotest.exe”: 已加载“C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.21022.8_none_96748342450f6aa2\msvcr90d.dll”,已加载符号。
“demotest.exe”: 已加载“C:\Windows\SysWOW64\apphelp.dll”
“demotest.exe”: 已加载“ImageAtBase0x4a2d0000”,未加载任何符号。
“demotest.exe”: 已卸载“ImageAtBase0x4a2d0000”
程序“[3204] demotest.exe: 本机”已退出,返回值为 0 (0x0)。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achou.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值