当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)。