一、前言:
创建一个对象的时候,常常需要作某些初始化的工作,例如对数据成员赋初值。注意,类的数据成员是不能在声明类时初始化的。
为了解决这个问题,C++编译器提供了构造函数(constructor)来处理对象的初始化。构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用它,而是在建立对象时自动执行。
二、构造函数
1、定义:
- 在C++中的类可以定义与类名同名的特殊成员函数,这种与类名相同的成员函数叫做构造函数
- 构造函数在定义时候可以有参数,也可以没有参数
- 没有任何返回类型声明
2、无参构造函数:
//-1-
class Box
{
public:
char name[20];
int age;
public:
/*默认构造函数, 无参
如果Box()没有自己定义,会自动生成
*/
Box()
{cout<<"Box()"<< endl;}
};
//-2-
class Box
{
public:
//无参的构造函数,,构造函数都目的,对类内的某些成员变量经行初始化
// :后边的数是对类内成员变量进行的初始化
Box():p(_len),sum(1000),n(100)
{
cout << "Box()" << endl;
_h=10;
_len=10;
_w=10;
}
private:
int _len;
int _w;
int _h;
int & p;
const int sum ;
};
无参数构造函数的调用机制:
Box a,b;//自动调用无参(默认的)构造函数 (a.Box()) Box x[4];
注意:Box a(); //不是构造对象,而是代表声明一个函数!!
3、有参构造函数
//有参的构造函数
Box(int len ,int w,int h)//与无参的函数形成函数重载
{
cout << "Box()_val" << endl;
//相当于赋值
_h=h;
_len=len;
_w=w;
}
有参函数的调用机制:
Box a(10,20,30);//调用Box(int len ,int w,int h)函数
4、注意
如果类中实现了带参数的构造函数,一定要实现一个无参的构造函数,因为如果在构造对象的时候不带参数将无法找到无参的构造函数导致编译失败。
5、初始化成员列表
Box(int len ,int w,int h):_len(len),_w(w),_h(h),p(_len),sum(1000),n(100)//实现效果相等
{
cout << "member list Box()_val" << endl;
// _h=h;
// _len=len;
// _w=w;
}
- 由逗号分隔的初始化列表组成(前面带冒号)
- 位于参数列表的右括号之后、函数体左括号之前
- 如果数据成员的名称为mdata,并需要将它初始化为val,则初始化器为mdata(val)
疑问:初始化成员列表什么时候必须要使用呢?
1、成员变量是引用的时候
2、成员变量被const修饰的时候
3、成员变量是另外一个类的实例化对象,且对应的类中没有实现无参构造函数的时候
举例:#include <iostream> using namespace std; //在类中调用类 class C { public: C(int i) { cout << i << endl; } private: int a; }; class Box { public: //无参的构造函数,,构造函数都目的,对类内的某些成员变量经行初始化 Box():p(_len),sum(1000),n(100) { cout << "Box()" << endl; } Box(int len ,int w,int h):n(100)//实现效果相等 { cout << "member list Box()_val" << endl; // _h=h; // _len=len; // _w=w; } private: int _len; int _w; int _h; int & p; const int sum ; C n; }
6、举例使用方式与总结:
#include <iostream> using namespace std; //在类中调用类 class C { public: C(int i) { cout <<"i="<<i << endl; } private: int a; }; class Box { public: //无参的构造函数,,构造函数都目的,对类内的某些成员变量经行初始化 Box():p(_len),sum(1000),n(100) { cout << "Box()" << endl; _h=10; _len=10; _w=10; } #if 0 //有参的构造函数 Box(int len ,int w,int h)//与无参的函数形成函数重载 { cout << "Box()_val" << endl; _h=h;//相当于赋值 _len=len; _w=w; } #endif /*初始化成员列表: * 由逗号分隔的初始化列表组成(前边带冒号) * 位于参数列表的右括号之后函数体左括号之前 * 如果数据成员变量的名称为mdata,并将它初始化为val,则初始化器为(mdata(val)) * 通过初始化成员列表实现对引用,和const修饰的成员变量进行初始化,要在所有的构造函数上声明 * 当被调用的类中没有C()(默认构造函数(无参构造函数))类型的时候,需要跳过,在该类的构造函数里经行初始化成员类表 * 以上三种必须要初始化成员列表 */ #if 1 Box(int len ,int w,int h):_len(len),_w(w),_h(h),p(_len),sum(1000),n(100)//实现效果相等 { cout << "member list Box()_val" << endl; // _h=h; // _len=len; // _w=w; } #endif int get_len(){ return _len;} int get_h(){ return _h;} int get_w(){ return _w;} int get_p(){ return p;} int get_sum(){return sum;} private: int _len; int _w; int _h; int & p; const int sum ; C n; }; int main() { Box a,b;//自动调用无参(默认的)构造函数 (a.Box()) Box x[4]; // Box c();//不是实例化一个对象,而是声明一个函数,返回值为Box,函数的名字叫做c,函数的形参列表为空 cout << a.get_w() <<endl; cout << a.get_h() <<endl; cout << a.get_len() << endl; Box c(40,30,20);//自动触发Box()有参有、构造函数的调用 cout << c.get_w() <<endl; cout << c.get_h() <<endl; cout << c.get_len() << endl; cout << c.get_p() << endl; cout << c.get_sum() << endl; return 0; }
/*
* 构造函数的总结
* 构造一个对象一定会自动调用一个构造函数
* 如果一个类中没有实现默认构造函数,编译器会自动生成一个前提是没有带参数的构造函数
* 如果一个类中实现了带参数的构造函数,一定要实现一个无参数的构造函数,因为在构造对象的时候,不带参数将无法找到无参构造函数导致编译失败
* 构造函数可以有多个,根据构造函数时所需要传递的参数,会自动调用对应的构造函数
* 类不回占用程序的内存空间,对象才会占用程序的内存空间。
* */