有时,所有函数的实现都不能在基类中提供,因为我们不知道实现。这样的类称为抽象类。例如,让Shape作为基类。我们不能在Shape中提供函数draw()的实现,但我们知道每个派生类都必须有draw()的实现。类似地,动物类没有move()的实现(假设所有动物都移动),但所有动物都必须知道如何移动。我们不能创建抽象类的对象。 C++中的一个纯虚函数(或抽象函数)是一个 虚函数 对于它,我们可以有实现,但我们必须在派生类中重写该函数,否则派生类也将成为抽象类(有关我们在何处为此类函数提供实现的更多信息,请参阅本节) https://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation ).通过在声明中赋值0来声明纯虚函数。请参见下面的示例。
CPP
// An abstract class class Test { // Data members of class public : // Pure Virtual Function virtual void show() = 0; /* Other members */ }; |
一个完整的例子: 纯虚函数由抽象类派生的类实现。下面是一个简单的例子来说明这一点。
CPP
#include<iostream> using namespace std; class Base { int x; public : virtual void fun() = 0; int getX() { return x; } }; // This class inherits from Base and implements fun() class Derived: public Base { int y; public : void fun() { cout << "fun() called" ; } }; int main( void ) { Derived d; d.fun(); return 0; } |
输出:
fun() called
一些有趣的事实: 1) 如果一个类至少有一个纯虚函数,那么它就是抽象的。 在下面的示例中,Test是一个抽象类,因为它有一个纯虚函数show()。
C++
课堂测试 { int x; 公众: 虚拟void show()=0; int getX(){return x;} };
内部主(空) { 测试t; 返回0; }
输出:
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) 我们可以有抽象类类型的指针和引用。 例如,下面的程序运行良好。
CPP
#include<iostream> using namespace std; class Base { public : virtual void show() = 0; }; class Derived: public Base { public : void show() { cout << "In Derived " ; } }; int main( void ) { Base *bp = new Derived(); bp->show(); return 0; } |
输出:
In Derived
3) 如果我们不重写派生类中的纯虚函数,那么派生类也会变成抽象类。 下面的示例演示了同样的情况。
CPP
#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) 抽象类可以有构造函数。 例如,以下程序编译并运行良好。
CPP
#include<iostream> using namespace std; // An abstract class with constructor class Base { protected : int x; public : virtual void fun() = 0; Base( int i) { x = i; cout<< "Constructor of base called" ; } }; 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(); //object creation using pointer of base class Base *ptr= new Derived(6,7); ptr->fun(); return 0; } |
输出:
Constructor of base called x = 4, y = 5 Constructor of base called x = 6, y = 7
与Java的比较 在Java中,可以使用abstract关键字将类抽象化。类似地,通过使用abstract关键字,可以使函数成为纯虚函数或抽象函数。看见 Java中的抽象类 更多细节。 接口与抽象类: 接口没有任何方法的实现,可以将其视为方法声明的集合。在C++中,可以通过使所有方法都是纯虚拟的来模拟接口。在Java中,接口有一个单独的关键字。
我们可以把接口看作是C++中的头文件,就像在头文件中一样,我们只提供要实现它的类的主体。类似地,在java in接口中,我们只提供类的主体,并在实现它的任何类中编写实际代码。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。