C++中的纯虚函数与抽象类

有时,所有函数的实现都不能在基类中提供,因为我们不知道实现。这样的类称为抽象类。例如,让Shape作为基类。我们不能在Shape中提供函数draw()的实现,但我们知道每个派生类都必须有draw()的实现。类似地,动物类没有move()的实现(假设所有动物都移动),但所有动物都必须知道如何移动。我们不能创建抽象类的对象。 C++中的一个纯虚函数(或抽象函数)是一个 虚函数 对于它,我们可以有实现,但我们必须在派生类中重写该函数,否则派生类也将成为抽象类(有关我们在何处为此类函数提供实现的更多信息,请参阅本节) https://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation ).通过在声明中赋值0来声明纯虚函数。请参见下面的示例。

null

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++

//纯虚函数使类变得抽象 #包括 使用名称空间std;

课堂测试 { 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接口中,我们只提供类的主体,并在实现它的任何类中编写实际代码。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享