556________________________________Часть IV. Новые возможности C++
физм для вызова функции-члена (давайте назовем ее Drawpart) для каждого элемента массива. Листинг 20.4 показывает новую функцию-член paint для TChordGauge.
void TChordGauge::Paint(TDC& dc,'bool, TRectS) {
// Разумеется, в класс TGauge должны входить новые данные-члены,
// представляющие массив из TGhordGaugePart (назовем его
// gaugePart) и целое число, обозначающее текущее количество
// деталей в нашем индикаторе (numberOfParts)
for (int count = 0; count < numberOfParts; count++)
(
// gaugePart — это массив типа TChordGaugePart*
gaugePart[count]->DrawPart(dc) ;
}
Теперь функция paint всегда будет одной и той же независимо от того, из скольких частей будет состоять наш элемент управления TChordGauge (а функция PaintBorder и вовсе станет не нужна, поскольку ее задачи будут переданы одному из производных классов TChordGaugePart). Что нужно для того, чтобы объявить класс TChordGaugePart? В первую очередь ему нужна виртуальная функция Drawpart:
class TChordGaugePart
{
public:
TChordGaugePart() ;
virtual void Drawpart(TDC &dc) = 0;
);
Здесь мы определили функцию Drawpart принимающей контекст устройства, который опять же требуется для большинства графических функций Windows API. Но почему мы установили Drawpart равной нулю? Сделав это, мы превратили Drawpart в так называемую чистую виртуальную функцию (pure virtual function), что означает, что реализация Drawpart — это дело производных от TChordGaugePart классов. Зачем это вообще нужно? Рассмотрим на минуту родовой класс TChordGaugePart. На что он в действительности похож? На самом деле, ни на что, он слишком общий. В, примере rchordGauge у нас есть циферблат и лицевая часть, которые являются конечными производными классами от TChordGaugePart. В этих производных классах мы действительно определим Drawpart, и код будет выглядеть почти идентично коду Paint и PaintBorder, рассмотренному раньше. Любой класс, содержащий одну или более чисто виртуальных функций, называется абст-