文章目录
- 继承
- 继承的方式
- 继承存在同名成员
- 继承存在同名静态成员
- 多继承语法
- 菱形继承
继承
面向对象三大特性之一
父类:又叫基类
子类:派生类
语法:
class 子类 : 继承方式 父类
继承的方式
继承方式有三种:pubilc公共继承、protected保护继承、private私有继承
不管哪种继承方式,都无法继承到父类的私有成员
(事实上,子类也有继承到父类的私有成员,只是由编译器隐藏后访问不到,父类的私有成员被继承后,也会占用子类的内存空间)
名称 | 作用范围 | 结果 |
---|---|---|
public | 公共继承 | 父类的中成员是公共属性的,继承后在子类也是公共属性;父类的中成员是保护属性的,继承后在子类也是保护属性; |
protected | 保护继承 | 父类的中成员是公共属性或保护属性,继承后在子类都是保护属性; |
private | 私有继承 | 父类的中成员是公共属性或保护属性,继承后在子类都是私有属性; |
继承的基本使用
class Base{//定义父类
public: int a;
};
class Son:pubilc Base{//Son类公共继承Base类
};
int main(){ Son son;//实例化son类 son.a = 1;//使用从父类中继承过来的成员属性
}//
继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
继承存在同名成员
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
访问子类同名成员 直接访问即可
访问父类同名成员 需要加作用域
class Base{//定义父类
public:int a;//子类和父类都有一个a成员属性void fun(){//子类和父类都有一个fun成员函数 }void fun(int b){//父类fun成员函数重重载 }
}
class Son:pubilc Base{//Son类公共继承Base类
public:int a;//子类和父类都有一个a成员属性void fun(){//子类和父类都有一个fun成员函数 }
}
int main(){Son son;//实例化son类son.a = 1;//直接访问的是子类的ason.Base::a = 1;//加作用域访问从父类继承的ason.fun();//直接访问的是子类的fun()son.Base::fun();//加作用域访问从父类继承的fun()son.fun(10);//子类没有这个函数的用法,报错,并且无法使用父类的重载函数fun(int b)//因为当子类和父类有同名函数时,父类的同名函数都会被屏蔽,要访问应加作用域son.Base::fun(10);//正确使用父类的重载函数fun(int b)的方法
}
继承存在同名静态成员
问题:继承中同名的静态成员在子类对象上如何进行访问?
静态成员和非静态成员出现同名,处理方式一致
访问子类同名成员 直接访问即可
访问父类同名成员 需要加作用域
本质上时同一块内存,不管修改谁都一样;
class Base{//定义父类
public:static int a;
}int Base::a = 100;//静态成员属性,类类声明,类外定义class Son:pubilc Base{//Son类公共继承Base类
public:static int a;
}
int main(){Son son;//实例化son类//静态成员属性有两种访问方法//1.通过对象访问son.a = 1;//使用son对象自己的ason.Base::a = 1;//使用从父类中继承过来的a//2.通过类访问Son::a = 1;//使用Son类访问aSon::Base::a = 1;//使用Son类作用下的Base类访问a
}
多继承语法
一个类允许继承多个类,也就是说子类可以有多个父类
语法:
class 子类 :继承方式 父类1 , 继承方式 父类2...
多继承可能会引发父类中有同名成员出现,需要加作用域区分
class Base1{//定义父类1
public:int a;
}
class Base2{//定义父类2
public:int a;
}
class Son:pubilc Base1,pubilc Base2{//Son类公共继承Base类
public:int a;
}
int main(){Son son;//实例化son类son.a = 1;//使用自己的成员属性ason.Baes1::a = 1;//使用从父类Baes1中继承过来的成员属性ason.Baes2::a = 1;//使用从父类Baes2中继承过来的成员属性a
}
菱形继承
就假设类B1和B2都继承了A类,此时C类同时继承 B1和B2,这种情况就是菱形继承,又叫钻石继承
菱形继承会出现继承多个重复的数据,比如说,类B1和B2都继承了A类的num成员属性,C类同时继承 B1和B2,就会出现既有B1的num,又有B2的num,事实上C只需要用到一份num
处理方法:
继承前加virtual关键字后,变为虚继承
class A{
public:int num;
}
class Base1: virtual public A{//定义父类1
public:int a;
}
class Base2::virtual public A{//定义父类2
public:int a;
}
class Son:pubilc Base1,pubilc Base2{//Son类公共继承Base类}
这样当Son同时继承Base1和Base2时,虚继承Base1的a和Base2的a会被指向同一片内存