本文旨在讲解C++中构造函数(属于6个默认成员函数的一种)的相关特性!!!希望读完本篇文章,会让读者对构造函数有更深一步的认识!
注:这里就不解释什么是默认成员函数了!
构造函数的定义
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。
为什么要引进构造函数
编译器无法预期一个程序在执行过程中会在何时创建一些什么对象!而只能根据当时的上下文要求来创建。对象的初始化最好能通过运行时执行一个函数来完成,而且是在对象创建的同时完成!这个函数就是构造函数!
日期类的构造函数例子!
通过上文可以得出构造函数时用来对创建后的对象进行初始化的一种特殊函数,下面我们就通过一些代码来仔细观察构造函数是如何定义的,以及其相关的特性!
日期类无参构造函数
class Data
{
private:
int _year;
int _month;
int _day;
public:
//无参构造函数!不能进行传参!相当于将初始化定死了!!!
Data()
{
_year = 1;
_month = 1;
_day = 1;
}
void print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
};
int main()
{
Data d1;
d1.print();
}
顾名思义,所谓无参构造函数,就是指在定义构造函数的时候不进行传参,直接把初始化写死了,不方便下一次修改,但是需要注意的是,进行无参构造函数的定义时,在main时对d1进行创建时,不能加上括号,因为一旦加上括号,编译器就会默认将其认定为函数的声明,从而导致出错。
假设加上(),下面来看一下编译器给出的警告!
从警告可以看出,编译器将d1误认为是一个函数了,其返回值类型为Data,所以需要注意的是,当进行无参构造函数时,对对象的声明时不能加上括号!!!
既然介绍了无参构造函数,那么接下来再来看看有参构造函数的实现吧!
日期类有参构造函数
看下面一段代码即可观察出有参构造函数的实现方式!
class Data
{
private:
int _year;
int _month;
int _day;
public:
//构造函数传参!!!可以灵活使用!
Data(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
};
通过观察有参构造函数,可以看出我们可以灵活的对有参函数进行传参,进行我们所需要的初始化操作!下面看一下如何调用有参构造函数!代码如下!
在进行有参构造函数的调用时,我们必须加上括号,然后进行初始化操作,若是没有加上括号,那么编译器就会报错,下面来看一下没加括号编译器会报什么错!
从报错可以看出,编译器找不到合适的构造函数,因为我们存在自己定义的构造函数了,编译器不再自己编写构造函数,所以我们只能用我们定义的类型的构造函数,但是我们的构造函数时需要传参的,但是我们没有对其进行传参,那么编译器就会找不到相对于的接口,从而给出报错信息!
日期类全缺省构造函数
通过以上两种构造函数的实现,我们发现,当对构造函数进行全缺省传参时,会有更好的结果!所以我们通常采用全缺省构造函数,因为它真的是很香!!!下面是全缺省构造函数的实现!!
class Data
{
private:
int _year;
int _month;
int _day;
public:
//当对构造函数进行全缺省时,可以加括号,也可以不加括号! 若进行传参必须加括号,不传参的话一定不能加扩号!!!否则编译器会误以为是一种函数的声明!!!!
Data(int year=1, int month=1, int day=1)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
}
对于全缺省构造函数还需要注意的是:当对构造函数进行全缺省时,可以加括号,也可以不加括号! 若进行传参必须加括号,不传参的话一定不能加扩号!!!否则编译器会误以为是一种函数的声明!!!!
构造函数的七大特性!
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载。
5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
6.编译器生成默认的构造函数只会对自定类型成员调用的它的默认成员函数。
7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个(若存在多个默认构造函数,则会导致代码的二义性,不能使编译器正确识别该调用哪个函数)。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
附:1.不要在构造函数内做与初始化对象无关的工作,也就是说,构造函数应该做能够满足正确初始化一个对象的最少工作量!否则会降低效率,甚至可能会让人误解!
2.最好为每一个类显式地定义构造函数,即使它空着,尤其是当类含有指针成员或引用成员的时候!
3.若程序员没有显式地定义构造函数,那么编译器会自动生成相应的函数,但是这些函数只能对用户定义的成员进行初始化。(用户定义的成员类型有:结构体,联合体,枚举等!)。
至此,关于C++中构造函数的讲解结束,希望能读者们有一定的收获,若有错误,望指出,定及时改正!