您的位置:首页 > 编程语言 > C语言/C++

纯虚函数和抽象基类

2015-03-17 11:03 155 查看
纯虚函数的格式:

virtual <类型> <函数名> (参数表) =0;


而我们的纯虚函数经常被用来构建抽象基类。

抽象基类:当我们仅想对基类进行向上类型转换,使用它的接口,而不希望用户实际地创建一个基类的对象,那么我们就在基类中加入至少一个纯虚函数(pure virtual function),来使基类称为抽象(abstract)类。

当继承一个抽象类时,必须实现所有的纯虚函数,否则继承出的类也将是一个抽象类。

实例:

//Pure abstract base classes
#include <iostream>
using namespace std;
//enum note {middleC,Csharp,Cflat};

class Instrument
{
public:
//Pure virtual functions:
//  virtual void play(note) const =0;
virtual void play() const =0;
virtual const char* what() const =0;
//Assume this will modify the object:
virtual void adjust(int) =0;
};
//Rest of the file is the same...

class Wind: public Instrument
{
public:
void play() const
{
cout<< "Wind::play" <<endl;
}

const char* what() const
{
return "Wind";
}

void adjust(int)
{
cout<<"Wind.adjust()"<<endl;
}
};

class Stringed: public Instrument
{
public:
void play() const
{
cout<<"Stringed::play"<<endl;
}

const char* what() const
{
return "Stringed";
}

void adjust(int){}
};

class Brass: public Wind
{
public:
void play() const
{
cout<<"Brass::play"<<endl;
}

const char* what() const
{
return "Brass";
}
};

//Identical function from before:
void tune(Instrument& i)
{
//...
i.play();
}

//New function:
void f(Instrument& i)
{
i.adjust(1);
}

int main()
{
Wind flute;
Stringed violin;
Brass flugelhorn;

tune(flute);
tune(violin);
tune(flugelhorn);

f(flugelhorn);
}


以上代码中,Instrument的目的是对所有从它派生出来的类创建公共接口。

既然是接口,那么我们实际上并不需要实例化Instrument对象,那么写成纯虚函数的目的也是让编译器禁止实例化。

纯虚函数告诉编译器在VTABLE中为函数保留一个位置,但在这个特定位置中不放地址,那么VTABLE就是不完全的,所以编译器就在实例化时发出一个出错信息。

这里需要注意,纯虚函数禁止对抽象类的函数以传值方式调用。这是防止对象切片(object slicing)的一种方法。通过抽象类,可以保证在向上类型转换器件总是使用指针或引用。

以上代码的执行结果:

Wind::play

Stringed::play

Brass::play

Wind.adjust()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 抽象类 纯虚函数