2010-12-21 20:44


派生子类会继承基类的所有成员,除了构造函数和析构函数。也就是说子类是无法继承父类的构造函数和析构函数的.因此,子类对于从父类继承过来的成员变量,若不想自己写构造函数初始化时,就只能先初始化父类中的成员变量,然后再继承过来。如以下程序中:

      子类Student1中的构造方法只有对新增成员int age和string addr的初始化操作,对于从父类继承过来的成员num,name,sex无初始化语句,但子类又不能继承父类的构造方法,要么就另外再写一个初始化语句,可这样操作就造成了重复性语句, 此时就得通过Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s) {age=a;addr=ad;}先初始化父类成员变量,从而间接初始化子类从父类继承过来的成员变量。

#include<iostream>
    #include<string>
    using namespace std;
    class Student
    {
    public:
    Student(int n,string nam,char s)
    {
       num=n;
       name=nam;
       sex=s;
       }
       ~Student(){}
       protected:
       int num;
       string name;
       char sex;
       };
       class Student1:public Student
      {
          Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)
          {
             age=a;
             addr=ad;
           }
          void show()
          {
           }
        private:
        int age;
        string addr;   
    };       
    int main()
    {
      Student1 stud1(10010,"Wang",'f',19,"BeiJing Road,Shanghai");
      ......
      ......
    }

    以上是对基类Student及子类Student1的定义。

    请注意派生子类构造函数首行的写法:

 

Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)

    其一般形式为

       派生类构造函数名(总参数列表):基类构造函数名(参数列表)

       {

          派生类中新增数据成员初始化语句;

        }

    冒号前面的部分是派生类构造函数的主干,它的总参数表列中包括基类构造函数所需的参数和对派生类新增的数据成员初始化所需的参数。冒号后面的部分是要调用的基类构造函数及其参数。

    基类构造函数后面括号内的参数表列中只有参数但无参数类型,因为在这里不是定义基类构造函数,而是调用基类构造函数,因此这些参数是实参而不是形参。他们可以是常量、全局变量和派生类构造函数总参数表中的参数。     

    从以上可以看到:在main函数中,建立对象stud1时,有5个参数,其中前3个是用来传递基类构造函数的,后2个用来对派生子类所增加的数据成员初始化。

    上例中也可以将派生类构造函数在类外定义,

Student1::Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)
    {
      age=a;
      addr=ad;
    }

    注:在类中对派生子类构造函数作声明时不需要:Student(n,nam,s),只有定义式才用到。

    以上例子中,调用基类构造函数时的实参是从子类构造函数的总参数表中获得的,也可以不从那传递,直接使用常量或全局变量,如:

 

Student1(string nam,char s,int a,string ad):Student(10010,nam,s)

    这样父类的n默认初始化为10010,子类直接把n=10010继承过来,因此所以不用写。