zoukankan      html  css  js  c++  java
  • 类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 once
    class 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类的中纯虚函数变成虚函数并实现它,则可以把注释的部分打开就可以编译。

  • 相关阅读:
    asp.net 对母版页的控件事件
    treeview操作集合
    使用GAppProxy时安全证书无效的解决办法
    向Excel模板中添加数据
    C# 重写 winform 关闭按钮
    完整ASP.Net Excel导入程序(支持2007)
    随笔二则
    标记枚举(flags)的使用
    System.Reflection.Missing.Value与Type.Missing
    Windows下Android源码下载方法
  • 原文地址:https://www.cnblogs.com/yagzh2000/p/2177779.html
Copyright © 2011-2022 走看看