构造函数的作用主要是对数据成员完成初始化。前面提到过,父类的构造函数是不能被继承到子类的,因此,对继承过来的父类成员的初始化造作也要由子类的构造函数完成。
解决这个问题的思路是:在执行子类的构造函数时,调用父类的构造函数。
一:简单的子类的构造函数:
#include<iostream>
using namespace std;
class Student
{
public:Student(int n)
{num = n;}
~Student(){}
protected:
int num;
};
class Student1 :public Student
{
public :
Student1(int n,int m):Student(n) //子类的构造函数
{age = m;}
~Student(){}
void display()
{
cout<< "num="<<num<<endl;
cout<<"age="<<age<<endl;
}
private:
int age;
};
void main()
{
Student1 stu1(23,12);
stu1.display();
}
注意上面例子中子类的构造函数定义后跟着父类的构造函数,初始化父类的成员,再在后面初始化子类的成员,这其实就是参数初始化列表,即可以用参数初始化列表调用父类的构造函数实现对父类成员的初始化。
二:有子对象的子类的构造函数:
所谓子对象,就是类中的数据成员是类对象,比如:
Student s; // Student是已经声明的类名。
#include<iostream>
using namespace std;
class Student
{
public:Student(int n)
{num = n;}
~Student(){}
protected:
int num;
};
class Student1 :public Student
{
public :
Student1(int n,int m,int k):Student(n),monitor(k) //子类的构造函数
{age = m;}
void display()
{
cout<< "num="<<num<<endl;
cout<<"age="<<age<<endl;
}
private:
Student monitor; //定义子对象:monitor
int age;
};
void main()
{
Student1 stu1(23,12,13);
stu1.display();
}
注意在子类中有一个私有成员:Student monitor;
它是父类Student 的对象,应该在建立对象时进行成员初始化,但不能在子类声明它时初始化,因为类只是一个抽象模型,是不能有具体数据的。因此子对象的初始化是在建立派生类时通过调用子类的构造函数来实现的。
注意执行子类的构造函数的顺序:
1,调用父类的构造函数,对父类成员初始化
2.调用子对象的构造函数,对子对象成员初始化
3.调用子类的构造函数,对子类成员初始化
三:多层继承时的构造函数:
在这里不举例子,只给出结论,多层继承不需要写出每一层的派生类的构造函数,只需要写出其上一层派生类(即它的直接父类)的构造函数,比如在上面程序的基础上增加一个类Student2,让它公有继承Student1,则其构造函数应这样写:
假设Student2中新增私有成员 int a;
Student2(int n,int m,int k,int b):Student1(n,m,k),a(b){}
不需要在里面加入Student的构造函数。
注意如果父类定义了无参的构造函数或者默认构造函数,则子类构造函数不需要引用父类的构造函数。
如果父类即定义了有参的构造函数,也定义了无参的构造函数,则子类写不写都可以,系统会根据要求调用合适的。
有一种特殊情况时虚基类,在子类中不仅要对直接父类初始化,还要对虚基类初始化,见http://write.blog.csdn.net/postedit/70046146
四:多重继承时的构造函数:
多重继承子类的构造函数形式与单继承时的构造函数形式基本相同,只是在初始化列中包含多个父类的构造函数,中间用逗号隔开即可。