Смекни!
smekni.com

Методические указания к курсу программирования для студентов физического факультета Сравнительное объектно-ориентированное проектирование (стр. 4 из 8)

__property TSprite* Items[int Index]={read=GetItems};

// Конструктор

__fastcall TSpriteList(TControlCanvas* const);

// Деструктор

__fastcall virtual ~TSpriteList();

// Методы

TSprite* __fastcall AddSprite(TSprite* const);

void __fastcall MoveSprite(int const, int const);

void __fastcall virtual DeleteSprite(int const);

void __fastcall virtual Clear();

};

// Тип массива следов спрайтов на канве

typedef DynamicArray< DynamicArray < bool > > TTraceMap;

//TTracedSpriteList

class TTracedSpriteList:public TSpriteList

{

private:

// Поле

TTraceMap traceMap;

public:

// Свойство

__property TTraceMap TraceMap = {read=traceMap};

// Конструктор

__fastcall TTracedSpriteList(TControlCanvas* const);

// Деструктор

__fastcall ~TTracedSpriteList();

// Методы

void __fastcall virtual DeleteSprite(int const);

void __fastcall virtual Clear();

};

typedef bool __fastcall(__closure *OnMoveEvent)(TSprite* ,TPoint&);

//TSprite

class TSprite:public TObject

{

// Класс TSpriteList, объявленный friend, получает доступ

// к private и protected членам класса TSprite

friend class TSpriteList;

private:

// Поля

bool visible;

int z;

TSpriteList* spriteList;

OnMoveEvent onMove;

TSize size;

TPoint location;

Graphics::TBitmap* image;

bool mask;

// Методы

void __fastcall SetVisible(bool const);

TRect __fastcall GetSpriteRect();

void __fastcall BeginPaint();

void __fastcall EndPaint();

void __fastcall SetMask(int const);

bool __fastcall Intersect(int const,int const);

protected:

// Методы

void __fastcall virtual PaintPicture()=0;

void __fastcall virtual Restore();

void __fastcall virtual Paint();

public:

// Свойства

__property bool Visible={read=visible,write=SetVisible};

__property int Z={read=z};

__property TSpriteList* SpriteList={read=spriteList};

__property OnMoveEvent OnMove={read=onMove,write=onMove};

__property TSize Size={read=size};

__property TPoint Location={read=location};

__property TRect SpriteRect={read=GetSpriteRect};

// Конструктор

__fastcall TSprite(TRect const);

// Деструктор

__fastcall virtual ~TSprite();

// Методы

bool __fastcall virtual Move(TSize const);

bool __fastcall virtual MoveTo(TPoint const);

};

// Тип динамического массива точек со следами спрайта

typedef DynamicArray <TPoint> TTracePoints;

//TTracedSprite

class TTracedSprite:public TSprite

{

private:

// Поля

TTracePoints trPoints;

bool traced;

bool traceColored;

TColor traceColor;

TPoint center;

// Метод

void __fastcall SetTraceColor(TColor const);

public:

// Свойство

__property TTracePoints TrPoints={read=trPoints};

__property bool Traced={read=traced,write=traced};

__property TColor TraceColor={read=traceColor,write=SetTraceColor};

__property bool TraceColored={read=traceColored,write=traceColored};

__property TPoint Center={read=center};

// Конструктор

__fastcall TTracedSprite(TRect const);

// Деструктор

__fastcall ~TTracedSprite();

// Методы

bool __fastcall virtual Move(TSize const);

void __fastcall PutTrace();

};

const TColor DefaultColor=0xffffff;

//TEllipseSprite

class TEllipseSprite:public TTracedSprite

{

private:

// Поле

TColor color;

protected:

// Методы

void __fastcall virtual PaintPicture();

void __fastcall SetColor(TColor const);

public:

// Свойство

__property TColor Color={read=color, write=SetColor};

// Конструктор

__fastcall TEllipseSprite(TRect const);

};

bool Contains(TRect const source,TRect const dest)

{

return source.Left>=dest.Left && source.Top>=dest.Top &&

source.Right<=dest.Right && source.Bottom<=dest.Bottom;

}

#endif

Весь код хэдера заключен «в скобки» защитного блокиратора вида

#ifndef uSpriteH

#define uSpriteH

#endif

Это директивы компилятору, которые переводятся так

#ifndef uSpriteH – если не определен символ uSpriteH

#define uSpriteH – определи символ uSpriteH

#endif – заверши область действия директивы «если».

Таким образом, если перед началом компиляции модуля символ uSpriteH определен, то все, что находится дальше вплоть до директивы #endif , то есть все операторы модуля, компилироваться не будут. Символ uSpriteH определяется при первой компиляции, когда он еще не определен, поэтому все повторные компиляции модуля блокируются.

Рассмотрим отдельные фрагменты кода.

class TSprite;

//TSpriteList

class TSpriteList

{

private:

// Поля

int count;

TControlCanvas* canvas;

void __fastcall SetVisible(bool const);

TRect __fastcall GetSpriteRect();

__property int Count = {read=count};

__property TSprite* Items[int Index]={read=GetItems};

// Конструктор

__fastcall TSpriteList(TControlCanvas* const);

// Деструктор

__fastcall virtual ~TSpriteList();

TSprite* __fastcall AddSprite(TSprite* const);

}

Здесь

· В описании типов и переменных на языке C в начале указывается идентификатор типа или тип, а затем имя типа или переменной: class TSpriteList или int count.

· Описание членов класса заключается в фигурные скобки. Эти скобки в C играют также роль ограничителей begin, end в Delphi.

· В описании TControlCanvas* canvas; стоит звездочка *. Это описание в языке С означает, что поле canvas является ссылкой на объект класса TControlCanvas, т.е. просто целым числом, содержащим адрес объекта в памяти. Если звездочку опустить, то canvas будет описана как объект типа TControlCanvas «по значению», т.е. содержать в себе все поля объекта типа TControlCanvas. В языке C описание объекта по значению приводит к тому, что в месте описания происходит создание реального экземпляра объекта – вызывается его «конструктор по умолчанию» и все поля инициализируются.

· В языке C нет процедур, как в Delphi, - только функции. Те функции, которые не возвращают значений, имеют тип void. Они являются аналогами процедур в Delphi.

· В C++ Builder в описании всех методов классов участвует модификатор __fastcall. Его смысл - обеспечить компиляцию в наиболее быстрый способ вызова метода при выполнении кода.

· В языке C даже, если функция не имеет параметров, в ее описании должны стоять скобки как в GetSpriteRect().

· В отличие от Delphi транслятор с языка C различает прописные и строчные буквы. Поэтому принято давать одинаковые имена полям и соответствующим свойствам, но начинать имена полей со строчной буквы, а свойств – с прописной буквы. Сравните, к примеру, описания поля count и свойства Count.

· Обратите внимание на синтаксис описания свойств в C++ Builder.

· Конструктор в C++ отличается от других методов тем, что его имя совпадает с именем класса и что он не возвращает никакой тип, даже void.

· Имя деструктора также совпадает с именем класса, но перед именем дается знак отрицания ~. Как и констуктор, деструктор не возвращает какой-либо тип. Кроме того, деструктор не должен иметь параметров. Деструктор часто объявляется виртуальным. В этом случае деструкторы всех наследников автоматически становятся виртуальными.

· В C++ модификатор virtual у виртуальных методов не заменяется у наследников на override, а остается virtual.

· В реализации на C++ у метода AddSprite есть только один параметр – ссылка на объект класса TSprite. Поэтому при обращении к методу AddSprite объект спрайта должен быть уже создан. В C++ нет возможности вызвать конструктор объекта, тип класса которого является переменной, как это делается в Delphi.

· При описании заголовков метода в хэдере языка C можно не указывать явно идентификаторы параметров – достаточно только типы. Так, в заголовке метода AddSprite указан только тип единственного параметра TSprite* const. Модификатор const играет ту же роль, что и в Delphi – параметр, объявленный как const, - не меняет своего значения внутри функции.

Прокомментируем другой фрагмент кода.

// Тип массива следов спрайтов на канве

typedef DynamicArray< DynamicArray < bool > > TTraceMap;

//TTracedSpriteList

class TTracedSpriteList:public TSpriteList

{

};

typedef bool __fastcall(__closure *OnMoveEvent)(TSprite* ,TPoint&);

//TSprite

class TSprite:public TObject

{

// Класс TSpriteList, объявленный friend, получает доступ

// к private и protected членам класса TSprite

friend class TSpriteList;

protected:

// Методы

void __fastcall virtual PaintPicture()=0;

};

Здесь

· Служебное слово typedef указывает на описание типа (подобно type в Delphi).

· Типом динамического массива, названного TTraceMap, является выражение DynamicArray< DynamicArray < bool > >. Оно имеет смысл двумерного массива («массива массивов») переменных логического типа. Имя DynamicArray является именем стандартного шаблона (template), находящегося в библиотеке C++Builder. Это параметризованные, или полиморфные (generic) функции. В Delphi нет аналогов шаблонам. Аргументом шаблона является тип. В данном случае аргументом внутреннего шаблона DynamicArray является тип bool, а аргументом внешнего – сам возвращаемый тип внутреннего шаблона DynamicArray< bool >.

· Класс TTracedSpriteList является наследником класса TSpriteList. В заголовке описания класса TTracedSpriteList присутствует ссылка на наследник TSpriteList с модификатором public. Модификатор public в данном контексте означает, что все члены, наследуемые от TSpriteList, сохраняют свою, заданную предком, доступность и в наследнике (public остается public и т.д.). Если бы модификатором был protected, то все наследуемые члены класса, объявленные в предке с модификаторами public и protected, приобрели бы в наследнике модификатор protected.