C++继承

来源:互联网 发布:提升应变能力 知乎 编辑:程序博客网 时间:2024/06/09 14:14

C++的继承

对于继承方式最常用是公有继承,对于私有继承与保护继承本文不做讨论。

先举个例子

#include <stdio.h>class A{public:A()//构造函数不能继承,如果私有该类不能继承{printf("construct A\n");}virtual ~A()////析构函数不能继承,如果私有该类不能继承,设置为virtual主要是为了利用多态编程是防止子类的资源没有释放{printf("delete A\n");}        virtual void fun1()  //这个函数再子类里面不重新实现,这就是普通的继承,子类继承了类A,子类的对象可以调用该函数。{printf("A fun1\n");}virtual void fun2() //这个函数再子类里面重新实现,这就是多态实现,子类继承了类A,子类覆写了函数,多态的具体实现。{printf("A fun2\n");}};class B:public A{public:B(){printf("construct B\n");}virtual ~B(){printf("delete B\n");}virtual void fun2() //子类覆写改函数{printf("override fun2\n");}};


1.基类函数的构造函数与析构函数是无法继承的,其他的函数可以继承,如果基类的构造函数或者析构函数设为私有,那么这个类是无法继承的,这点要注意,不过有时编程就利用这个特性,比如设计模式中的单例模式需要用到这个特性。如果基类里面的函数声明了关键字virtual(构造函数不能加上关键字virtual),那么子类里面继承了该函数,继承的函数默认也为virtual,是否加上关键字virtual对函数没有影响,在C++多态的文章里面说过,子类是否加上关键字virtual对实现多态不会有影响,但是建议还是显示加上关键字virtual,这样使程序易读。


2.析构函数的关键字virtual

当一个析构函数被标记为virtual时,其所有派生类的析构函数将自动成为virtual(不管它们是否标记为virtual),析构函数的这种行为好像基类与派生类的析构函数都具有相同的名字一样,尽管实际上它们的析构函数的名字是不一样的,对于第一点,如果子类重写的同名的函数,将自动加上关键字virtual,析构函数的名字虽然不一样,但同样自动成为virtual。


3.继承调用与多态

子类可以继承父类的所有函数,这点与多态调用区分开来,定义了一个指向父类的指针,这个指针能够调用的函数一定是在父类里面定义了的。如果定义一个对于指向派生类的指针,因为是继承,所有父类里面的方法都是继承过来,虽然没有在子类里面父类的函数没有显示定义,但是是可以调用的,虽然函数上显示的调用的是父类的函数。

区分A* p1=new B();这种写法与B* p2=new B();这种写法,很简单的一种学习的方法,在代码中写下p1,p2然后看看p1,p2分别能够调用的函数就非常容易理解了。p1是多态,p2是继承调用,区分开来。p1->~A()与delete p1实现的效果一样,p2->~B()与delete p2也一样。


4.继承中构造函数,析构函数,普通函数的调用

无论是通过多态实现子类的实例化,还是普通的实例化,都是先调用父类的构造函数,再调用子类的构造函数。方法1,多态实现实例化A* p1=new B();方法2,普通实例化B* p2=new B();对于析构函数来说,如果是通过多态来实例化,也就是方法1,那么基类的析构函数一定要加上关键字virtual,否则会出现仅仅调用了父类的析构函数而没有调用子类的析构函数,如果是普通实例化,也就是方法2,父类与子类的析构函数都会按顺序调用,无论是否加上关键字virtual,虽然这样,但是仍然建议父类与子类的析构函数上都加上关键字virtual。

5.区分能继承与能访问的区别

父类如果有一个函数为私有,通过公有继承继承父类,子类是继承了这个私有函数,但是子类是无法访问这个函数的,继承与访问时不一样的,这点要区分开来。




0 0
原创粉丝点击