13.1.4 构造函数
构造函数就是构造类的实例时,系统自动调用的成员函数。当一个对象被创建时,它是否能够被正确地初始化,在C++(www.cppentry.com)中是通过构造函数来解决问题的。每当对象被声明或者在堆栈中被分配时,构造函数即被调用。构造函数是一种特殊的类成员,其函数名和类名相同,声明格式如下:
- <函数名>(<参数列表>);
【示例13-6】 演示构造函数的使用方法。
- class student
- {
- private:
- int id;
- float chinese,english,math;
- public:
-
- student();
-
- student(int m_id,float m_chinese,float m_english,float m_math);
- void show();
- }
-
- student::student()
- {
- id=0;
- chinese=english=math=0;
- }
-
- student(int m_id,char * m_name,float m_chinese,float m_english,float m_math)
- {
- id=m_id;
- chinese=m_chinese;
- english=m_english;
- math=m_math;
- }
- student::show()
- {
- cout<<id<<endl;
- cout<<chinese<<endl;
- cout<<english<<endl;
- cout<<math<<endl;
- }
分析:该示例定义了两个构造函数,第一个构造函数不带参数,所有属性都被初始化为0。第二个构造函数带参数,用传入的参数来初始化类的属性。构造函数的个数没有限制,可以根据需要定义多个,每个都针对不同的初始化情况。
在定义和使用构造函数时要注意以下几个问题:
构造函数的名字必须与类名相同,否则编译程序将把它作为一般的成员函数来处理;
构造函数没有返回值,在声明和定义构造函数时是不能说明它的类型的;
构造函数的功能是对对象进行初始化,因此在构造函数中只能对属性做初始化,这些属性一般为私有成员;
构造函数不能像其他方法一样被显式地调用。
下面通过示例13-6中的类student,来说明构造函数使用上应该注意的几个问题。
1.构造函数的调用
【示例13-7】 演示类student的构造函数调用的方法。
- int main()
- {
- student s1;
- student s2(1,60,70,80);
-
- s1.show();
- s2.show();
- return 0;
- }
程序运行结果如下:
- 0
- 0
- 0
- 0
- 1
- 60
- 70
- 80
分析:从输出结果看,在main函数中,构造函数没有被显式调用,而在初始化对象时自动调用。其中,s1调用的构造函数是不带参数的student(),s2调用的则是带参数的构造函数。代码中注释掉的语句是错误的,构造函数不能被显式调用。
2.拷贝构造函数
拷贝构造函数是一种特殊的构造函数,即复制另一个对象的构造函数。一般在下述3种情况下会用到拷贝构造函数:
用一个类对象显式初始化另一个类对象;
把类对象作为实参传递给函数;
将类对象作为函数的返回值时。
在这些情况下,系统就会自动调用拷贝构造函数,将参数代表的对象中的属性逐个拷贝到新创建的对象中。拷贝构造函数有两种形式:系统默认形式和自定义形式。
【示例13-8】 演示系统默认形式的使用方法。
- int main()
- {
- student s1(1,80,90,85);
- s1.show();
- student s2(s1);
- s2.show();
- return 0;
- }
程序运行结果如下:
- 1
- 80
- 90
- 85
- 1
- 80
- 90
- 85
分析:对象s1在定义时,调用了带参数的构造函数。在定义对象s2时,采用了student s2(s1)的形式,此时调用的是系统默认的拷贝构造函数。拷贝构造函数将s1对象的属性都复制给了s2对象相应的属性中。因此,s2对象的属性值与s1对象的属性值相同。
自定义形式的构造函数的声明方式如下:
- <类名>::<函数名>(<类名>&<参数名>)
- {
-
- }
【示例13-9】 给示例13-6增加一个具有自定义拷贝构造功能的构造函数,演示自定义形式的使用方法。
-
-
-
- inline student::student(const student &s)
- {
- id=s.id;
- name=s.name;
- chinese=s.chinese;
- english=s.english;
- math=s.math;
- }
- void main()
- {
- student s1(1,80,90,85);
- s1.show();
- student s2(s1);
- s2.show();
- }
程序运行结果如下:
- 1
- 80
- 90
- 85
- 1
- 80
- 90
- 85
分析:当定义s2时,采用student s2(s1)的形式,调用了用户自定义的拷贝构造函数。实际上,拷贝构造函数就是用类作为构造函数的参数。
提示:如果类不定义构造函数,则编译器生成默认构造函数。这种构造函数不进行任何初始化,因此生成对象时,不能保证处于一致状态。
【责任编辑:
云霞 TEL:(010)68476606】