C++虚函数(11) - 纯虚函数与抽象类

目录

1.纯虚函数与抽象类

2.纯虚函数的特性

2.1纯虚函数与抽象类

2.2使用抽象类的指针或引用

2.3子类中的纯虚函数

3.抽象类可以有构造函数

4.与Java比较


1.纯虚函数与抽象类

有时候并不是所有的函数都能在基类中实现,因为无法确定具体实现。这样的一个类成为抽象类。
例如:将Shape定义为基类,我们无法确定Shape类中的draw()方法的具体实现,但是可以确定每个子类必须实现draw()。
类似地,一个Animal类无法确定move()方法的实现,但是所有的具体animal是知道move()的实现的。

抽象类不能创建具体对象。

C++中的纯虚函数(或抽象函数)就是一个无法实现的虚函数,只是声明它。纯虚函数在声明时赋值为0。

参考下面例子:

// 抽象类
class Test
{  
public:
    // 纯虚函数
    virtual void show() = 0;
 };

下面是一个完整例子:纯虚函数在抽象类的继承类中实现。

#include<iostream>
using namespace std;
class Base
{
   int x;
public:
    virtual void fun() = 0;
    int getX() { return x; }
};
//此类继承自Base类,并实现了fun方法
class Derived: public Base
{
    int y;
public:
    void fun() { cout << "fun() called"; }
};
int main(void)
{
    Derived d;
    d.fun();
    return 0;
}

运行结果:
fun() called

2.纯虚函数的特性

2.1纯虚函数与抽象类

至少拥有一个纯虚函数才是抽象类。
下面例子中,Test是一个抽象类,因为它包含了一个纯虚函数show()。

#include<iostream>
using namespace std;
class Test
{
   int x;
public:
    virtual void show() = 0;
    int getX() { return x; }
};
 
int main(void)
{
    Test t;
    return 0;
}

编译失败,因为Test是一个抽象类。
Compiler Error: cannot declare variable 't' to be of abstract type 'Test' because the following virtual functions are pure within 'Test': note:
virtual void Test::show() 

2.2使用抽象类的指针或引用

虽然抽象类不能直接创建具体对象,但可以使用它的指针或者引用。
下面程序工作正常。

#include<iostream>
using namespace std;
 
class Base
{
public:
    virtual void show() = 0;
};
 
class Derived: public Base
{
public:
    void show() { cout << "In Derived \n"; }
};
 
int main(void)
{
    Base *bp = new Derived();
    bp->show();
    return 0;
}

运行结果:
In Derived

2.3子类中的纯虚函数

如果子类中不覆写这个纯虚函数,则子类也会变为抽象类。

参考下面程序。

#include<iostream>
using namespace std;
class Base
{
public:
    virtual void show() = 0;
};
 
class Derived : public Base { };

int main(void)
{
  Derived d;
  return 0;
}

编译错误:
Compiler Error: cannot declare variable 'd' to be of abstract type 'Derived' because the following virtual functions are pure within 'Derived': virtual void Base::show()4)

3.抽象类可以有构造函数

下面程序工作正常

#include<iostream>
using namespace std;

//带有构造函数的抽象类
class Base {
protected:
    int x;
public:
    virtual void fun() = 0;
    Base(int i) { x = i; }
};

class Derived : public Base {
    int y;
public:
    Derived(int i, int j) :Base(i) { y = j; }
    void fun() { cout << "x = " << x << ", y = " << y; }
};

int main(void) {
    Derived d(4, 5);
    d.fun();
    return 0;
}

运行结果:
x = 4, y = 5

4.与Java比较

在Java中,可以使用关键字abstract声明一个抽象类。同样,可以使用abstract将一个函数声明为纯虚函数或抽象函数。

接口与抽象类:
一个接口不会实现它的任何方法,可以将其视作方法声明的收集。在C++中,接口类中会将其所有方法定义为纯虚。在Java中,有一个单独的关键字interface.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值