C++继承总结
经过最近一段时间的学习,对类的三大特性之一的继承性有所了解(其他俩是封装性,多态性)。
总的来说,继承不是在写代码的时候用的,而是在代码完成之后,优化代码用的,继承时我们把几个类共有的数据成员抽出作为基类而去使用,这样可以实现代码的复用,有效提高代码的简洁性,让代码看着更舒服。
语法格式
class 派生类名 : 基类名表
{
数据成员和成员函数声明
};
基类名表构成:访问控制 基类名
访问控制:private public protected
派生类经历了三个步骤
1.吸收基类成员(构造和析构函数除外,不一定可见)
2.改造基类成员(根据派生类成员函数,覆盖基类)
3.添加派生类新成员
派生类生成时候的空间是新申请的空间,与基类并不相同。
基类函数调用时,作用域限定即可。
重名成员
一般用重名成员函数,重名数据成员有用的必要的时候再去使用。
同名函数使用
#include<iostream>
using namespace std ;
class A
{ public:
int a1, a2 ;
A( int i1=0, int i2=0 ) { a1 = i1; a2 = i2; }
void print()
{ cout << "a1=" << a1 << '\t' << "a2=" << a2 << endl ; }
};
class B : public A
{ public:
int b1, b2 ;
B( int j1=1, int j2=1 ) { b1 = j1; b2 = j2; }
void print() //同名
{ cout << "b1=" << b1 << '\t' << "b2=" << b2 << endl ; }
基类的初始化
在创建派生类对象时,用指定参数调用基类的构造函数,初始化派生类继承基类的数据。
声明为
派生类构造函数 ( 变元表 ) : 基类 ( 变元表 ) , 对象成员1( 变元表 ).........;
构造函数顺序:基类->对象成员->派生类
一般来说基类可以定义一个无参的构造函数。
派生类构造函数析构函数使用原则:
1.基类的构造函数和析构函数不能被继承
2.如果基类没有定义构造函数或有无参的构造函数, 派生类也可以不用定义构造函数
3.如果基类没有无参的构造函数,派生类必须定义构造函数
4.如果派生类的基类也是派生类,则每个派生类只负责直接(也就是最近的)基类的构造
5.派生类是否定义析构函数与所属的基类无关
多继承
充满了二义性的一种继承,不建议使用。
赋值兼容规则
指程序中需要使用基类的地方可以用公有派生类的对象代替。
赋值兼容规则中所指的替代包括以下的情况:
1.派生类的对象可以赋给基类对象
2.派生类的对象可以初始化基类的引用
3.派生类的对象的地址可以赋给基类类型的指针(常用)
演示
class Person {…};
class Student : public Person { … };
void eat(Person &p){};
void study(Student &s){};
void main( )
{
Person p;
Student s;
eat(p); // OK
eat(s); // OK
study(s); // OK
study(p); // error C2664: “study”: 不能将参数 1 从“Person”转换Student &”(这或许就是中文翻译....)
}
只能派生类赋值给基类,基类无法赋值给派生类,道理很简单,因为派生类数据比基类多。