C++的继承

来源:互联网 发布:2016网络写手收入排行 编辑:程序博客网 时间:2024/05/02 02:56

一、继承的概念

继承是面向对象复用的重要手段。通过继承定义一个类,继承是类型之间的关系建模,共享公有的东西,实现各本质不同的东西。

二、三种继承方式

三种继承方式为:public(公有)、protected(私有)、private(保护)

继承方式
基类的public成员
基类的protected成员
基类的private成员
public继承
仍为public成员仍为protected成员
不可见protected继承
变为protected成员变为protected成员
不可见private继承
变为private成员变为private成员
不可见
注意:使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,最好显示的写出继承方式。

三、继承的格式

单继承:一个子类只有一个直接父类
class <派生类类名>  :<继承方式> <基类类名>
{
    <新定义的类成员>
}

多继承:一个子类有两个或两个以上直接父类
class <派生类类名>  :<继承方式> <基类类名>,<继承方式> <基类类名> ...
{
    <新定义的类成员> 
}

子类(即派生类)的构成:自定义的成员和继承来的成员


代码验证

class Base     //父类{public:void Display(){cout << "Display()" << endl;}public:int _age;};class Derive:public Base           //子类{public:void fun(){}public:int _num;};int main(){Base b1;b1._age = 1;Derive d1;d1._num = 2;d1._age = 3;return 0;}


四、继承与转换--赋值兼容规则--public继承

1.子类对象可以赋值给父类对象(切片/切割)
2.父类对象不能复制给子类对象
3.父类的指针/引用可以指向子类对象
4.子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)


菱形继承存在的问题:1.二义性
2.数据冗余问题
利用虚继承可以解决这两个问题。
五、虚函数

虚函数:类的成员函数前面家virtual关键字。

虚函数重写:当在子类中定义了一个与父类完全相同的虚函数时,则称子类的这个函数重写了父类的这个虚函数。

多态:当使用基类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,指向子类调用的就是子类的虚函数

class Person{public:virtual void BuyTIckets(){cout << "买票" << endl;}};class Student :public Person{public:virtual void BuyTIckets(){cout << "买半价票" << endl;}};void Fun(Person& p){p.BuyTIckets();}int main(){Person p;Student s;Fun(p);         //调用父类Fun(s);         //调用子类}
输出结果:


总结:

1.派生类重写基类的虚函数实现多态,要求函数名、参数列表、返回值完全相同(协变除外)

2.基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性。

3.只有类的成员函数才能定义为虚函数。

4.静态成员函数不能定义为虚函数。

5.如果在类外定义虚函数,只能在声明函数时加virtual,类外定义函数时不能加virtual。

6.构造函数不能为虚函数。

7.不要在构造函数和析构函数里面调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会发生未定义的行为。

纯虚函数:

在成员函数的形参后面加上=0,则成员函数为纯虚函数。

包含纯虚函数的类叫抽象类(接口类),抽象类不能实例化出对象。纯虚函数在派生类中重新定义以后,派生类才能实例化出对象。

六、友元与继承

友元关系不能继承,即基类友元不能访问子类私有和保护成员。

七、静态成员与继承

基类定义了static成员,则整个继承体系里面只有一个这样的成员,无论派生出多少个子类,都只有一个static成员实例。

八、重载、重写(覆盖)和重定义(隐藏)的区别:

重载:1.在同一作用域

2.函数名相同/参数不同

3.返回值可以不同

重写:1.不在同一作用域(分别在基类和派生类)

2.函数名相同/参数相同/返回值相同(协变例外)

3.基类函数必须有virtual关键字

4.访问修饰符可以不同

隐藏:1.在不同作用域(分别在基类和派生类)

2.函数名相同

3.在基类和派生类中只要不构成重写就是重定义。

0 0
原创粉丝点击