C++預設函數成員都不是虛擬函數,如果要將某個函數成員宣告為虛擬函數,則要加上"virtual"關鍵 字,然而C++提供一種語法定義「純虛擬函數」(Pure virtual function),指明某個函數只是提供一個介面,要求繼承的子類別必須重新定義該函數,定義純虛擬函數除了使用關鍵字"virtual"之外,要在函 數定義之后緊跟着'='并加上一個0,例如:
class Some {
public:
// 純虛擬函數
virtual void someFunction() = 0;
....
};
一個類別中如果含有虛擬函數,則該類別為一「抽象類別」(Abstract class),該類別只能被繼承,而不能用來直接生成實例,如果試圖使用一個抽象類別來生成實例,則會發生編譯錯誤。
以下舉個實際的例子,先假設您設計了兩個類別:ConcreteCircle與HollowCircle:
class ConcreteCircle {
public:
void radius(double radius) {
_radius = radius;
}
double radius() {
return _radius;
}
void render() {
cout << "畫一個半徑 "
<< _radius
<< " 的實心圓"
<< endl;
}
private:
double _radius;
};
class HollowCircle {
public:
void radius(double radius) {
_radius = radius;
}
double radius() {
return _radius;
}
void render() {
cout << "畫一個半徑 "
<< _radius
<< " 的空心圓"
<< endl;
}
private:
double _radius;
};
顯 然的,這兩個類別除了render()方法的實作內容不同之外,其它的定義是一樣的,而且這兩個類別所定義的顯然都是「圓」的一種類型,您可以定義一個抽 象的AbstractCircle類別,將ConcreteCircle與HollowCircle中相同的行為與定義提取(Pull up)至抽象類別中:
AbstractCircle.h
#ifndef ABSTRACTCIRCLE
#define ABSTRACTCIRCLE
class AbstractCircle {
public:
void radius(double radius) {
_radius = radius;
}
double radius() {
return _radius;
}
// 宣告虛擬函數
virtual void render() = 0;
protected:
double _radius;
};
#endif
注 意到在類別宣告了虛擬函數render(),所以AbstractCircle是個抽象類別,它只能被繼承,繼承了AbstractCircle的類別必 須實作render()函數,接着您可以讓ConcreteCircle與HollowCircle類別繼承AbstractCircle方法并實作 render()函數:
HollowCircle.h
#include <iostream>
#include "AbstractCircle.h"
using namespace std;
class HollowCircle : public AbstractCircle {
public:
void render() {
cout << "畫一個半徑 "
<< _radius
<< " 的空心圓"
<< endl;
}
};
ConcreteCircle.h
#include <iostream>
#include "AbstractCircle.h"
using namespace std;
class ConcreteCircle : public AbstractCircle {
public:
void render() {
cout << "畫一個半徑 "
<< _radius
<< " 的實心圓"
<< endl;
}
};
由 于共同的定義被提取至AbstractCircle類別中,并于衍生類別中繼承了下來,所以在ConcreteCircle與HollowCircle 中無需重復定義,只要定義個別對render()的處理方式就行了,而由于ConcreteCircle與HollowCircle都是 AbstractCircle的子類別,因而可以使用AbstractCircle上所定義的虛擬操作介面,來操作子類別實例上的方法,如下所示:
main.cpp
#include <iostream>
#include "AbstractCircle.h"
#include "ConcreteCircle.h"
#include "HollowCircle.h"
using namespace std;
void render(AbstractCircle &circle) {
circle.render();
}
int main() {
ConcreteCircle concrete;
concrete.radius(10.0);
render(concrete);
HollowCircle hollow;
hollow.radius(20.0);
render(hollow);
return 0;
}
執行結果:
畫一個半徑 10 的實心圓
畫一個半徑 20 的空心圓
//該文章來源于:<a href='http://www.violetblog.cn'>VioletBlog</a>
沒有留言:
張貼留言