26.继承和派生
(1)继承方式有三种:public(共有继承),private(私有继承)protected(保护继承)。 (2) 成员访问属性的改变: 基类的访问属性 继承方式 在派生类的访问属性 Private public 不可访问(不是private) Private protecetd 不可访问
Private private 不可访问
Protected public 保护 Protected protected 保护 Protected private 私有 Public public 公用 Public protected 保护 Public private 私有
(3)在操作派生时,先构造父类提供的成员,在构造对象成员,最后构造自己的成员变量。
比如定义类 时,先构
造父类的成员,按照从左往右的顺序(这里是先B 后A),然后构造对象成员,从上往下(这里是先e1,后d1)。最后对自身的变量n3的构造。如果向ABCDE类的构造函数都加一句输出该类类名的语句。则定义一个C类的对象C1 后,会输出:
(4) 由于类的构造函数不能显示调用,所以在上图的语句中,若要对ABDE的对象进行
初始化,不能直接在C的构造函数中写相应的构造函数。所以采用调用表的方法
特别的,其各个成员的构造顺序与调用表顺序无关。
(5) 在进行多重继承时,由于各个父类可能会存在同名变量,所以会引起二义性,解
决方案就是在变量前加上基类名和域运算符来解决。
27:虚基类
但是,用上述方法解决二义性明显不是很理想。所以我们引入了虚基类。
虚基类并不是在定义类时确定了,而是在继承的时候确定的。当继承多个父类有同一个函数时,只保留一个,这样就减少了二义性。
有此可见,虚基类的构造优先级大于基类。
总结:类里面构造函数的优先级 虚基类>基类>对象成员>自身成员。 基类与派生类的相互转换
基类对象不能给派生类对象赋值,因为基类对象的数据成员和成员函数不能满足派生类的要求。而派生类可以给基类赋值,赋值时会将基类以外的部分舍弃不用。同样的,同一基类的不同派生类对象之间也不能赋值。
28:多态性和虚函数
(1) (2)
只要是含有虚函数的类,我们都称为抽象类。 多态的实现分为以下步骤:
i:设置一个抽象类,并在内部设置一个抽象函数; ii:以该抽象类为基类,派生出各种相似的类别。
iii:在外部定义一个以基类的指针为参数的函数,函数体是通过->操作符访问该虚函数。
IV:用派生类的对象的地址作为该函数的参数来调用这个函数。
(3) 系统会自动的检查是否为虚函数,如果是的话,就到它派生出去的子类中,找到类
型一致的该函数实体,并执行它。 接下来给出一个虚函数的使用实例。
#include
class Student:public Person { int classid; int grade; public: Student (int id,char *name,int cid,int fenshu):Person(id,name) { classid=cid; grade=fenshu; } void show() { cout<<\ Person::show();
cout<<\ } };
class Teacher:public Person { char jobtitle[10]; char department[15]; public: Teacher(int id,char *name,char* jt,char* dm):Person(id,name) { strcpy(jobtitle,jt); strcpy(department,dm); } void show() { cout<<\ Person::show(); cout<<\ } };
void func(Person * p) { p->show(); }
int main() { Student s1(1000,\ }
Teacher t1(1095,\助教\信息管理\func(&s1); func(&t1); return 0;
(4) 纯虚函数
这里的函数f()就是纯虚函数。
通用的定义是:vitrual 函数类型 函数名(参数列表)=0;
后面的=0不是说明返回值为0,而是为了告诉系统,这个函数是纯虚函数。