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
};

 

 
posted @ 2019-05-02 16:32 王陸 阅读(...) 评论(...) 编辑 收藏