zoukankan      html  css  js  c++  java
  • C++ 纯虚函数和抽象类

    纯虚函数和定义

     
    在许多情况下,在基类中不能对虚函数给出有意义有实现,而把它说明为纯虚函数。纯虚函数是没有函数体的虚函数,它的实现留给该基类的派生类去做,这就是纯虚函数的作用。
     
    class A
    {
    private:
        int a;
    public:
        virtual void Print( ) = 0 ;   //纯虚函数
        void fun( )
        {
            cout << "fun";
        }
    };
    纯虚函数的标志是:在其声明后有一个特殊的语法  =0

    抽象类

    带有纯虚函数的类称为抽象类。抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的,它处于继承层次结构的较上层。
    充要条件至少有一个纯虚(pure virtual)方法。
    抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限。
    若一个类的构造函数声明为私有的,则该类和该类的派生类都不能创建对象;若构造函数声明为保护型,则该类不能创建对象,但它的派生类是可以创建对象的。
     
     抽象类通常有派生类-没有派生类的抽象类是多余的.
     
    例如
    class B1
    {
    protected:
        B1() {}
    };
    class B2
    {
    private:
        B2() {}
    };
    class D1 : public B1
    {
    public:
        D1() {}
    };
    class D2 : public B2
    {
    public:
        D2() {}  // error C2248: “B2::B2”: 无法访问 private 成员(在“B2”类中声明)
    };
    int main()
    {
        B1 b1;  // error C2248: “B1::B1”: 无法访问 protected 成员(在“B1”类中声明)
        B2 b2;  // error C2248: “B2::B2”: 无法访问 private 成员(在“B2”类中声明)
        D1 d1;  // OK
        D2 d2;  // error
        return 0;
    }
     
    抽象类只能作为基类来派生新类使用,不能创建抽象类的对象,但抽象类的指针和引用可以指向由抽象类派生出来的类的对象。
     
    A a ; // 错,A 是抽象类,不能创建对象
    A * pa ; // ok,可以定义抽象类的指针和引用
    pa = new A ; //错误, A 是抽象类,不能创建对象
    从抽象类派生的类必须实现基类的纯虚函数,否则该派生类也不能创建对象。
    class Base
    {
    public:
        virtual void func( ) = 0;
    };
    class Derived : public Base { }
    int main( )
    {
        Derived d;  //error C2259: “Derived”: 不能实例化抽象类
        return 0;
    }

    上例中,派生类中没有对基类的纯虚函数进行定义(派生类不重置基类的纯虚函数),那么派生类自身也就成了一个抽象类,无法被实例化。

     

    抽象类特征:

    1.可以有多个(≥1)纯虚方法;
    2.可以有非纯虚方法;
    3.可以有非虚方法;
    4.可以有数据成员;
    5.可以定义成员的访问控制(对外能见度)。
     
    其中后四点为所有类的共同特点。
    class ABC
    {
    public:
        ABC( )
        {
            …
        }
        ABC(int x)
        {
            …
        }
        ~ABC( )
        {
            …
        }
        virtual void open( ) = 0;
        virtual void print()
        {
            …
        }
        int getCount( )
        {
            …
        }
    private:
        int n;
    }

    抽象类用途

    1.抽象基类用来说明一族类的共同接口(shared interface).
     
     
    class BasicFile
    {
    public:
        virtual int open( ) =0;
        virtual int close( ) =0;
        virtual int flush( ) = 0;
    };
    class InFile : public BasicFile
    {
    public:
        virtual int open( )
        {
            …
        };
        virtual int close( )
        {
            …
        };
        virtual int flush( )
        {
            …
        };
    };
    class OutFile : public BasicFile
    {
    public:
        virtual int open( )
        {
            …
        };
        virtual int close( )
        {
            …
        };
        virtual int flush( )
        {
            …
        };
    };
     
    2.抽象类可以用来表明某种软件设计需求。
    class  IIntroSpect
    {
    public:
        virtual void listFields ( ) =0;
        virtual void listMethods( ) =0;
    };
    
    class MyClass : public IIntroSpect// 有实例的类
    {
    public:
        void listFields ( )
        {
            …
        };
        void listMethods( )
        {
            …
        };
        // other members of MyClass
    };
     
  • 相关阅读:
    C#.NET 以上超大文件上传和断点续传服务器的实现
    ASP.NET 以上超大文件上传和断点续传服务器的实现
    JSP 以上超大文件上传和断点续传服务器的实现
    Java 以上超大文件上传和断点续传服务器的实现
    4GB以上超大文件上传和断点续传服务器的源码
    4GB以上超大文件上传和断点续传服务器的代码
    4GB以上超大文件上传和断点续传服务器的实现
    hdu 1013 Digital Roots
    hdu 1012 u Calculate e
    hdu 1011 树形dp
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/10802625.html
Copyright © 2011-2022 走看看