💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目录
- 前言:
- 一、 什么是构造函数
- 二、构造函数的特征特征
- 三、构造函数类型
- 1.无参构造
- 2.带参构造函数
- 3.全缺省构造函数(后面有补充)
- (1)传入前一个,前两个,全传入。
- (2)传入0个参数时
- 四、默认构造函数意义:
- 1.问题引入:
- 2.内置类型和自定义类型
- 五、补充
- 后续补充!
前言:
使用类实例化对象时,每一个对象都要进行初始化,都要进行调用初始化函数,这个操作是实例化对象的必要操作,那么有没有更好的方式来简化这个调用操作。于是C++便推出了构造函数
一、 什么是构造函数
构造函数是特殊的成员函数,构造函数千万不要认为它是用来创建对象的,其实构造函数的主要任务并不是开空间创建对象,而是初始化对象。
- 没有构造函数,需要自己手动写初始化函数,如下:
class Data
{
public:
void Init(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
void print(){}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1;
d1.Init(1999, 1, 1);
d1.print();
Data d2;
d2.Init(2023, 1, 1);
d2.print();
return 0;
}
- 使用构造函数
class DData
{
public:
DData(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << "时间:" << _year << _month << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
DData d1(2023, 11, 14);
d1.print();
return 0;
}
二、构造函数的特征特征
函数名
与类名
相同。无
返回值。- 对象实例化时编译器
自动调用
对应的构造函数。 - 构造函数可以
重载
。
如上代码,两个Data构造函数,构成重载,但是不能同时存在,无参调用时会造成歧义(不知道调哪一个)。所以,在写构造函数时使用全缺省方式,更加合适。
三、构造函数类型
1.无参构造
格式:Data d1
class Data
{
public:
//这里不写构造函数
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1;
return 0;
}
2.带参构造函数
格式 Data d1(2023, 11, 14);对应构造函数中的三个参数
class DData
{
public:
//构造函数
Data(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << "时间:" << _year << _month << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2023, 11, 14);
d1.print();
return 0;
}
3.全缺省构造函数(后面有补充)
使用全缺省构造函数,它的特殊之处在于带有初始值。如果传参时没有覆盖,那么就会将自带的初始值赋给变量。
(1)传入前一个,前两个,全传入。
如下代码,我们只传入前两个参数或者只传入前一个参数又或是全传入。
Data d1(1999,6); 或者 Data d1(1999);或者Data d1(1999,6,6)
class DData
{
public:
//构造函数
Data(int year=1, int month=1, int day=1)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << "时间:" << _year << _month << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(1999,6);
d1.print();
return 0;
}
(2)传入0个参数时
当传入0个参数时,应该怎么写,会不会和无参构造冲突?
其实当传入0个参数时,我们应该写成Data d1
;而不能写成Data d1();的形式。写法与无参构造写法一样,但是,默认的无参构造函数不会进行初始化,而全缺省构造函数对其进行了初始化。
如下:
注意:
- 不能写成Data d1();否则就成了函数声明
- 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
四、默认构造函数意义:
默认构造的三种形式:
总结:可以不传参数调用的都叫默认构造
1.问题引入:
执行下面代码:
class Data
{
public:
void print()
{
cout << "时间 " << _year <<"+" << _month << "+" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1;
d1.print();
return 0;
}
可以发现,使用默认构造,变量都是随机值,并没有任何处理,这样说默认构造好像没有什么用啊!想要弄清楚这个问题,我们通过下面的学习。
2.内置类型和自定义类型
默认生成的构造函数对于:
内置类型
(如int,double,指针
等系统定义的类型): 不做处理自定义类型
(自己定义的类型,如自己定义的):会对其进行处理,会调用自定义类型的类中的构造函数,如果没有 ,那么也还是随机值。
如:定义了一个栈类,使用两个栈实现队列,这个队列中的数据类型有Stack类型的,当调用默认构造时,Stack类型的变量会去栈类中调用构造函数,为其赋初值。有点绕,但是写一份代码太麻烦了。(仅供自己理解)
五、补充
其实这种定义并不方便,更好的做法是,int就默认赋值0,double就默认赋值0.0等等。
所以在C++11中做出了补丁,也就是允许在类在声明变量时给缺省值。
class Data
{
public:
void print()
{
cout << "时间 " << _year <<"+" << _month << "+" << _day << endl;
}
private:
int _year =1;
int _month =1;
int _day =1;
};
变动的地方也就在这里:如下
我们前面说过,类中的成员变量都是声明,那么我们现在这样写是不是就是定义了呢?答案是它还是声明,并不是定义,没有开空间。
使用这种写法,我们在以后的声明中可以直接不写构造函数,让编译器默认自己生成构造函数。
例如:
class Data
{
public:
void print()
{
cout << "时间 " << _year <<"+" << _month << "+" << _day << endl;
}
private:
int _year = 1;
int _month = 1;
int _day = 1;
};
int main()
{
Data d1;
d1.print();
return 0;
}
总结:内置类型赋予了缺省值,或者成员变量都是自定义类型,可以直接使用默认的无参构造。