第四节 派生类和继承

来源:互联网 发布:做淘宝客服要交保证金 编辑:程序博客网 时间:2024/05/05 17:02

派生类的基本概念

 

class person{    //基类

private:

  char name[10];

  int age;

  char sex;

public:

  showname();

};

class employee:public person{    //子类

private:

  char department[20];

\  float salary;

public:

  showsalary();

};

//在子类里只需要定义添加的数据和函数

 

继承方式

private 

全部变私有,以前是私有的派生类中不能访问,但是以前是共有和保护的在派生类都能访问

缺省就是私有的

 

protected

共有变保护

 

public

不变

 

 

在派生类中定义与基类同名的成员

称派生类的成员覆盖了基类的同名成员

若要在派生类中使用与基类的同名成员可以使用作用域运算符

类名::成员

class X{

public:

  int f();

};

class Y:public X{

public:

  int f();

  void g();

};

void Y::g()

{

  f();

  X::f();

}

Y obj;

obj:f();

obj.X::f();

 

 

派生类的构造函数

要初始化自己的数据成员

又要调用基类的构造函数

class base{

  long number;

  char name[20],sex;

public:

  base(long num=0,char *n=\n,char s=m)

  {

number = num;

strcpy(name,n);  //是数字所以不用new开空间

sex = s;

  }

  void p_show()

  {

cout<<people number = <<number;

cout<< name = <<name<< sex = <<sex<<endl;

  }

  ~base(){}

};

class derive:public base{

  int s_num;

public:

  int s_class;

  base b;

  derive(long n, char *na, char s=m, int sn = 0, int sc = 0):base(n,na,s),b(n,na,s)

  {

s_num = sn;

s_class = sc;

  }

  void s_show()

  {

cout<<base: <<endl;

p_show();

cout<<s_sum=<<s_sum<< s_class=<<s_class<<endl;

  }

  ~derive(){}

};

 

...->基类的构造函数->派生类构造函数->派生类析构函数->基类析构函数...->

 

练习

class array{

private:

  int size;    //数组大小

  int *element;    //数组元素

public:

  array(int sz);

  ~array();

  int& elem(int i);   // 返回第i+1个元素

};

array::array(int sz)

{

  size = sz;

  element = new int[size];

}

 

array::~array(){delete []element;}

 

int &array::elem(int i)

{

  return *(element + i);

}

 

main()

{

  array a(5);

  a.elem(1) = 1;

}

 

 

class newarray:public array{

private:

  int I1,I2;

public:

  newarray(int i1,int i2);

  ~newarray();

  int &newelem(int i);

}

 

newarray::newarray(int i1, int i2):array(i2-i1+1)

{

  I1 = i1;

  I2 = i2;

}

newarray::~newarray(){}

int &newarray::newarray(int i)

{

  if (i < I1 || i > I2)

return 0;

  else

    return elem(i-i1);

}

 

 

 

多重继承

派生类与每一个基类之间的关系仍为单一继承

 

当基类的成员函数或者数据成员有同名的出现了二义性

class A{

public:

  void f();

};

class B{

public:

  void f();

  void g();

};

class C:public A, public B{

public:

  void f();

  void g();

};

C obj;

obj.A::f();

obj.B::f();

obj.g();

obj.B::g();

 

 

虚基类

如果一个派生类从多个基类派生,而这些直接基类又有一个共同的基类,则在派生类的内存中存在该基类的多个副本,在对从该基类继承而来的成员进行访问时,就可能产生二义性

A      A

 \      /

  B   C

   \  /

    D

 

将直接基类的共同基类设置为虚基类。这时,从不同路径继承来的该基类成员在派生类的内存中只拥有一个副本,有关公共基类成员访问的二义性问题就不存在了

   A     //A作为虚基类

  /  \

B    C

  \  /

   D

 

eg:

class base{

};

class base1:virtual public base{

};

class base2:virtual public base{

};

class derived:public base1,public base2{

  int d;

public:

  derived(int sa, int sb, int sc,int sd):base(sa),base1(sa,sb),base2(sa,sc)

  {

    d=sd;

    cout<<constructing derived<<endl; 

  }

};

 

当一个类的虚基类时,编译系统为该类对象定义一个指针成员使它指向虚基类的子对象,该指针被称为虚基类指针

0 0
原创粉丝点击