类5-类的继承、虚函数、纯虚函数、虚析构函数

一、类的继承

就像家谱一样,就是一个继承图。爷爷-父亲-儿子-孙子等.类也一样,上面的类称为基类,也称父类。基类下面的类叫子类也叫派生类。

子类对父类的一些属性等有所继承也有所发展,因此才有了类的继承。

C++中类的继承格式为:

class ChildClass:public ParentClass;

子类后面要加上冒号及类限制符(public\protected\private)和基类。

class CExample{  public:  ...  protected:  ...  private:  ...}

在一个类中,会有三个访问限制符。

public 是公共,公开的意思,只要有对象访问CExample类,则它的public部分是可以被此对象访问的。

如果是子类来继承的话,子类可以访问基本中这部分的信息。

protected 是保护的意思,即只有本类和子类可以访问这部分内容,其它的对象是不可以访问的。

private 是私有的,即只有本类可以访问这部分内容,其它的对象没有访问权限。

如果我们在继承基类的时候,如直接这样写:

class CSample:CParent;

此时省略了限制访问类符号,系统默认是private级的,这时就会把基类中protected和public的成员全变成子类的private区内,基类的private 是不能访问的。

如果为protected,则只能访问父类中的protected及public,而public成员也在子类中变成protected属性.

如果为public,则父类中的protected也变成public。

记住以下三点:

如果基类被声明为private,其成员在派生类中永远不可访问。

如果基类被声明为protected, 其public成员在派生类中将成为protected.

如果其类被声明为public,其在派生类中的访问级别保持不变。

二、类的虚函数

什么叫虚函数?就是此函数已在父类中定义,但其在子类中可能要重新再定义。

一般是在函数头前加上 virtual关键字。如 virtual type showinfo() const;

三、类的纯虚函数

在基类中我们声明了一个函数成员,但没有给出具体实现,因为这个类只是一种很泛的抽象,具体实现函数的功能要在派生类中实现。它的格式为:

virtual type showinfo() const=0;

即在虚函数后面加上=0即可。

这样的类也叫抽象类,抽象类不能实例化。

四、类的虚析构函数

类的虚折构函数在动态产生对象后并用delete删除时有用,如果不是动态产生对象就不用做这样的声明。

平常我们是静态编译的,在析构时,程序也是静态连接的,这时系统知道父类和子类之间的关系,就会先析构子类再析构父类。而在动态产生一个对象时,如下面的例子:

Cparent* p=0;  p=new CChild(100);  delete p;

在此类中,Cparent类为CChild的父类,我们此时声明Cparent指针p.因为是动态在自由存储区中分配的,而p又被声明为Cparent类型的指针,但在赋值时却指向子类。但在销毁时,系统认为它是cparent类型的,故会调用Cparent的析构函数,而子类的析构函数不会被执行。这就是我们用虚析构函数的原因。

因此:我们在类的继承时,总是把类的析构函数声明为虚析构函数是个好主意。

但构造函数是没有虚的,切记!

以下为代码:

Box.h

#pragma onceclass CBox{public:    CBox(double lv,double wv, double hv);    CBox();    virtual double volume() const;    double getlength() const;protected:    virtual void printclassInfo()=0;    double m_length;    double m_width;    double m_height;};

Box.cpp

#include "Box.h"#include <iostream>using namespace std;CBox::CBox(double lv,double wv,double hv):m_length(lv),m_width(wv),m_height(hv){   printf("Constructor Called!\n");}CBox::CBox(){    printf("Default construct!\n");}double CBox::volume() const{    return m_height*m_width*m_length;}double CBox::getlength() const{    return m_length;}

ChildBox.h

#pragma once#include "Box.h"class CChildBox:public CBox{public:    CChildBox(double lv,double wv,double hv);    double volume() const;    virtual void printclassInfo();};

ChildBox.cpp

#include "ChildBox.h"#include <iostream>using namespace std;CChildBox::CChildBox(double lv,double wv,double hv):CBox(){  m_length=lv;  m_width=wv;  m_height=hv;  printf("CChildBox Construct Called!\n");    }double CChildBox::volume() const{  return 3*3*3;  } void CChildBox::printclassInfo(){    printf("CChildBox\n");}

main.cpp

#include "ChildBox.h"#include <iostream>using namespace std;void output(CBox& abox){    cout<<endl        <<abox.volume()<<endl;}void main(){    CChildBox childbox(12,22,33);        //CBox box(3,0.3,3.5);        CBox* p=0;    p=&childbox;    printf("The volume is: %0.2f \n",p->volume());    printf("the getlength is: %0.2f\n",p->getlength());    output(childbox);    childbox.printclassInfo();    /*p=&box;    printf("The volume is: %0.2f \n",p->volume());    output(box);*/}

本例中,我们把代码的头和定义分开了。

另因为CBox是抽象类,所以不能实例化它,故把main中的部分代码注释掉了,如果要把CBox类的中纯虚函数变成虚函数并实现它,则可以把注释的部分打开就可以编译。

原文链接: https://www.cnblogs.com/yagzh2000/archive/2011/09/15/2177779.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/32356

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午9:36
下一篇 2023年2月8日 上午9:37

相关推荐