继承意味着可以为一个类定义并编译一个非常泛化的形式。C++最强大的特性之一就是可通过继承,从一个类派生出另一个类。继承是根据一个类(称为基类)创建一个新类(称为派生类)的过程。派生类自动具有基类的所有成员变量和函数,并可根据需要添加更多的成员函数和成员变量。
派生类 派生类的定义和类的定义类似,只是在类定义的第一行添加了一个冒号、保留字public和基类的名称,例如:
class
HourlyEmployee
:
public
Employee {};
表示定义一个类HourlyEmployee,该类是Employee的继承类。派生类自动继承基类所有的成员变量和函数,在派生类中,只给出了新增成员变量和成员函数。
派生类中的构造函数 基类中的构造函数不由派生类继承,但是可以在派生类构造函数的定义中调用基类的构造函数。派生类构造函数可以首先调用基类构造函数,初始化从基类中继承的数据,使用一种特殊的语法调用基类的构造函数,例如:
HourlyEmployee::HourlyEmployee(
string
the_name ,
string
the_number ,
double
the_wage_rate,
double
the_hours )
:
Employee(
the_name,
the_number), wage_rate(
the_wage_rate ), hours(
the_hours){}
::后面的部分即为构造函数,其中,
Employee(
the_name,
the_number)是对基类构造函数的调用,调用基类双参赛构造函数,传递
the_name,
the_number的值。
HourlyEmployee的另一个构造函数是:
HourlyEmployee::HourlyEmployee() :
Employee (), wage_rate(), hours(0) {}
Employee ()表示调用基类无参数的构造函数。在派生类构造函数的初始化区域,应该坚持包括对其中一个基类构造函数的调用。如果派生类的构造函数定义不包括对基类构造函数的调用,就会自动调用基类构造函数的默认(无参数)版本,假如基类没有默认的构造函数,就会出错。所有,在HourlyEmployee类的默认构造函数定义中,省略
Employee (),即
HourlyEmployee::HourlyEmployee() : wage_rate(), hours(0) {} 与上述构造函数效果相同。
派生类继承过程中的私有成员变量 派生类不能直接访问基类中的私有成员变量,必须使用基类中定义的公共取值和赋值成员函数。取值函数是允许访问一个类的成员变量的函数,而赋值函数是允许更改一个类的成员变量的函数。除非是在基类的接口中实现,否则不能直接访问私有成员变量或者成员函数——即使是在派生类的一个成员函数的定义中。私有成员函数根本不会继承。
protected限定符 不能在派生类的定义或实现中访问一个私有成员变量或者私有成员函数。但是,还有另一种成员变量和成员函数,可以(而且只能)在派生类中根据名称直接访问。在不是拍摄类的其他任何类总,则不能访问这种成员。在一个类诶的成员变量或者成员函数之前,如果添加限定符protected,那么对于除派生类植物的任何类或者函数来说,它的效果等同于用private来标记的成员,但在派生类中,可以根据名称来访问这些成员。
重定义成员函数 定义派生类时,只需要明确列出需要修改定义的那些继承成员函数的声明。派生类继承基类的所有成员函数和成员变量,但是如果一个派生类需要以不同的方式来实现一个继承的成员函数,就可以在派生类中重新定义这个函数。要重定义一个函数,必须在派生类的定义中列出它的声明。
重定义与重载的比较 重定义函数时,派生类中给出的新函数定义具有相同的参数数量和类型。如果派生类中的函数使用了数量不同的参数,或者某个参数具有不同的类型,那么派生类中实际会拥有两个函数,这正是函数重载的概念,不能说是重定义。
访问重定义的基函数 函数在派生类中重定义后,如果要在派生类中调用重定义的函数,需要使用域解析操作符,并指定基类的名称。例如,定义一个HourlyEmployee类的对象,HourlyEmployee sally_h,而要调用基类Employee的print_check() 函数,那么调用方式为:
sally_h.Employee::print_check()
函数的签名 是指函数名以及参数列表中的类型序列,但是不包括关键字const和符合&。以这个签名的定义为准,重载一个函数名称时,函数名称的两个定义必须具有不同的签名。在派生类中,如果一个函数与基类中的函数同名,但是具有不同的签名,那么就是函数的重载而不是重定义。