Green-sell.info

Новые технологии
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Структура point c

Структуры в языке C#

Вы уже знаете, что классы относятся к ссылочным типам данных. Это означает, что объекты конкретного класса доступны по ссылке. Ссылка -это 32/64-х битный адрес, указывающий на расположение членов-данных в управляемой куче, в отличие от значений простых типов, доступных непосредственно.

Но иногда прямой доступ к объектам (например, как к значениям простых типов) полезно иметь ради повышения эффективности программы. Ведь каждый доступ к объектам по ссылке связан с дополнительными издержками на расход вычислительных ресурсов и оперативной памяти.

Для разрешения подобных затруднений в C# предусмотрена структура, которая подобна классу, но относится к типу значений, а не к ссылочному типу данных.

Структуры отличаются от классов тем, как они сохраняются в памяти и как к ним осуществляется доступ (для начала – краткая формула «классы — это ссылочные типы, размещаемые в куче, структуры — типы значений, размещаемые в стеке»). Эта формула не совсем точная, пояснения см. позже. Структуры отличаются от классов некоторыми свойствами (например, структуры не поддерживают наследование).

Из соображений производительности следует использовать структуры для небольших типов данных. Однако в отношении синтаксиса структуры очень похожи на классы.

Первое и очевидное отличие состоит в том, что при их объявлении используется ключевое слово struct вместо class. Ниже приведена общая форма объявления структуры:

struct имя
<
объявления членов
>
где имя обозначает конкретное имя структуры.

Как у класса, так и у каждой структуры имеются свои члены: методы, поля, индексаторы, свойства, операторные методы и события. Так в структуре Double (библиотека System) определено 6 констант, 6 операторов отношения, 19 методов, 5 интерфейсов (проверьте, используя интеллектуальную подсказку). Не многовато ли для вещественного числа, как вы думаете?

В структурах допускается также определять конструкторы. В то же время для структуры нельзя определить конструктор, используемый по умолчанию (без параметров), который определяется для всех структур автоматически и не подлежит изменению. Такой конструктор инициализирует поля структуры значениями, задаваемыми по умолчанию (false для типа bool, 0 – для чисел). А поскольку структуры в отличие от классов не поддерживают наследование, то их члены нельзя указывать как abstract, virtual или protected.

Экземпляр (можно говорить и «объект») структуры может быть создан с помощью оператора new таким же образом, как и объект класса, но в этом нет особой необходимости. Когда используется оператор new, то вызывается конструктор, используемый по умолчанию. А когда этот оператор не используется, объект по-прежнему создается, хотя и не инициализируется. В этом случае инициализацию любых членов структуры придется выполнить вручную. Рассмотрим пример.

Результат выполнения программы:


Исследуем программу. Закомментируем вторую строку в методе Main():
// stud1.name = «Петр»;
При запуске программы получим сообщение об ошибке:
Использование локальной переменной «stud1», которой не присвоено значение.
Хотя структура stud1 объявлена, но полю name никакого значения не присвоено, что приводит к ошибке. Такая же ошибка возникнет, если мы станем использовать переменную целого типа, которая объявлена, но не инициализирована.
Такой вот жесткий контроль компилятора за нашими действиями!

Проверим, как работает конструктор без параметров. Первую строку метода Main() заменим на
student stud1 = new student();
Вторую и третью строку – закомментируем. Тогда при выводе результата в 1 строке получим:
студент 1: Имя: , возраст: 0
Следовательно, полю name была присвоена пустая строка, а полю возраст – число 0.

Проверим, как работает защита данных. В второй строке описания структуры student удалим модификатор поля public, т.е. получим byte age;
При запуске программы получим два сообщения об ошибке:
«ConsoleApplication1.student.age» недоступен из-за его уровня защиты
в операторах stud1.age = 18; и stud2.age = 19;

Это означает, что так как по умолчанию поле age является полем private, то оно не может быть изменено в другом классе с помощью оператора присваивания, однако оно доступно методам класса student, объявленным как public. С учетом этих результатов, программа может быть записана так:

Здесь поля объектов stud1 и stud2 структуры student являются private-полями, а метод и конструктор объявлены как public.

А теперь ВНИМАНИЕ! Ключевая идея — Создание сложных конструкций данных, используя один тип данных, как элемент другой конструкции. В статье про типы данных мы выяснили, что все встроенные типы, относящиеся к типам значений (их еще называют простыми типами данных), являются структурами, хотя фактически каждая из них имеет одно поле, содержащее значение числа, символа или булевой переменной.

Структура позволяет объединять несколько различных по типу элементов под одним именем. Более того можно использовать неоднократное вложение одних типов данных в другие, используя структуры.

Для понимания этой идеи рассмотрим пример. Прототипом для него являются структуры из библиотеки System. Drawing: Point, Size и Rectangle.

Известно, что точка на экране задается парой целых чисел (X,Y) в пикселях. Объединим эти два числа в структуру точка. Установим максимальную защиту (private – по умолчанию) для этих полей. Добавим конструктор с параметрами точка(x,y) для инициализации объектов структуры точка, а также метод Get() для извлечения полей в строковом формате.

Размер прямоугольника на экране также задается парой чисел: шириной и высотой. Соответственно объявим структуру размер с полями (W,H). Добавим аналогичный конструктор с параметрами размер(w,h) для инициализации объектов структуры размер, а также метод Get() для извлечения полей в строковом формате.

Прямоугольник на экране определяется координатами верхнего левого угла (точка) и размером изображения (размер). Поэтому третью структуру построим на основе первых двух, назовем ее Rect (сокращенно от «прямоугольник»), полями которой будут объекты первых двух структур: точка P и размер S. Эти поля также будут защищенными (private – по умолчанию). Добавим в эту структуру конструктор с параметрами public Rect(int x, int y, int w, int h) и три метода: Get() для извлечения информации о прямоугольнике, Get_P() и Get_S для извлечения координат и размеров по отдельности.

В методе Main( ) последовательно инициализируем объект Rect r и покажем работу методов всех этих трех структур.


Конечно, если бы поля всех структур были объявлены с модификатором public, то в принципе можно обходиться структурами, имеющими только поля без методов. Но помня о том, что структуры похожи на классы, следует и к ним применять те же общие принципы, что и для классов в части защиты данных.

Структуры

Введение

Мир вокруг можно моделировать различными способами. Самым естественным из них является представление о нём, как о наборе объектов. У каждого объекта есть свои свойства. Например, для человека это возраст, пол, рост, вес и т.д. Для велосипеда – тип, размер колёс, вес, материал, изготовитель и пр. Для товара в магазине – идентификационный номер, название, группа, вес, цена, скидка и т.д.

У классов объектов набор этих свойств одинаковый: все собаки могут быть описаны, с той или иной точностью, одинаковым набором свойств, но значения этих свойств будут разные.

Все самолёты обладают набором общих свойств в пределах одного класса. Если же нам надо более точное описание, то можно выделить подклассы: самолёт амфибии, боевые истребители, пассажирские лайнеры – и в пределах уже этих классов описывать объекты. Например, нам необходимо хранить информацию о сотрудниках компании. Каждый сотрудник, в общем, обладает большим количеством разных свойств. Мы выберем только те, которые нас интересуют для решения прикладной задачи: пол, имя, фамилия, возраст, идентификационный номер. Для работы с таким объектом нам необходима конструкция, которая бы могла агрегировать различные типы данных под одним именем. Для этих целей в си используются структуры.

Читать еще:  Hp не подключается к wifi

Объявление структуры

Синтаксис объявления структуры

Полями структуры могут быть любые объявленные типы, кроме самой структуры этого же типа, но можно хранить указатель на структуру этого типа:

В том случае, если несколько полей имеют один тип, то их можно перечислить через запятую:

После того, как мы объявили структуру, можно создавать переменную такого типа с использованием служебного слова struct. Доступ до полей структуры осуществляется с помощью операции точка:

Структура, объявленная в глобальном контексте, видна всем. Структура также может быть объявлена внутри функции:

Можно упростить пример: синтаксис языка позволяет создавать экземпляры структуры сразу же после определения:

Структура также может быть анонимной. Тогда мы не сможем использовать имя структуры в дальнейшем.

В этом примере мы создали переменную A. Она является структурой с двумя полями.

Начальная инициализация структур

Структуру можно инициализировать во время создания как массив. Поля в этом случае будут присваиваться по порядку.

Замечание: таким образом можно только иницализировать структуру. Присваивать значение всей структуре таким образом нельзя.

Современный стандарт си позволяет инициализировать поля структуры по имени. Для этого используется следующий синтакис:

Определение нового типа

Когда мы определяем новую структуру с помощью служебного слова struct, в пространстве имён структур (оно не имеет ничего общего с пространствами имён С++) создаётся новый идентификатор. Для доступа к нему необходимо использовать служебное слово struct. Можно определить новый тип с помощью служебного слова typedef. Тогда будет создан псевдоним для нашей структуры, видимый в глобальном контексте.

Теперь при работе с типом Point нет необходимости каждый раз писать слово struct. Два объявления можно объединить в одно

Замечание. Если мы создаём новый тип-структуру, полем которого является указатель на этот же тип, то его необходимо объявлять явно с использованием служебного слова struct

Указатели на структуру

Указатель на структуру создаётся как обычно. Отличие заключается в том, что можно обращаться к полям структуры через указатель с помощью операции «стрелка» (минус + больше). Пример – пользователь вводит число – размер массива пользователей. Поле этого вводит для каждого из них логин и пароль. Третье поле — идентификатор – задаётся автоматически. После этого все пользователи выводятся на экран.

Обратите внимание на удаление массива структур: при удалении экземпляра структуры он не удаляет своих полей самостоятельно, поэтому необходимо сначала удалять поля, после этого удалять сам массив.
При вызове функции jsonUser мы передаём указатель на экземпляр структуры, поэтому внутри функции доступ до полей осуществляется с помощью оператора стрелка.

Устройство структуры в памяти

Поля структуры расположены в памяти друг за другом. Тип поля определяет сдвиг относительно предыдущего поля. Имя поля — это сдвиг относительно адреса экземпляра. На самом деле размер структуры не всегда равен сумме размеров её полей: это связано с тем, что компилятор оптимизирует расположение структуры в памяти и может поля небольшого размера подгонять до чётных адресов.

Первая структура должна иметь размер 6 байт, вторая 8 байт, третья 7 байт, однако на 32-разрядной машине компилятор VC сделает их все три равными 8 байт. Стандарт гарантирует, что поля расположены друг за другом, но не гарантирует, что непрерывно.

Есть возможность изменить упаковку структур в памяти. Можно явно указать компилятору каким образом производить упаковку полей структуры, объединений или полей класса. Каким образом это делать, зависит от компилятора. Один из самых распространённых способов прагма pack()

У неё есть несколько разновидностей, рассмотрим только одну. pragma pack(n) указывает значение в байтах, используемое для упаковки. Если параметр компилятора не заданы для модуля значения по умолчанию n 8. Допустимыми значениями являются 1, 2, 4, 8 и 16. Выравнивание поля происходит по адресу, кратному n или сумме нескольких полей объекта, в зависимости от того, какая из этих величин меньше.

Использование #pragma pack не приветствуется: логика работы программы не должна зависить от внутреннего представления структуры (если, конечно, вы не занимаетесь системным программированием или ломаете чужие программы и сети).

Приведение типов

Стандартом поведение при приведении одной структуры к другой не определено. Это значит, что даже если структуры имеют одинаковые поля, то нельзя явно кастовать одну структуру до другой.

Этот пример работает, но это хак, которого необходимо избегать. Правильно писать так

Привести массив к структуре (или любому другому типу) по стандарту также невозможно (хотя в различных компиляторах есть для этого инструменты).
Но в си возможно всё.

Но запомните, что в данном случае поведение не определено.

Вложенные структуры

Структура сама может являться полем структуры. Пример: структура Model – модель автомобиля, имеет название, номер, год выпуска и поле Make, которое в свою очередь хранит номер марки и её название.

Вложенные структуры инициализируются как многомерные массивы. В предыдущем примере можно произвести начальную инициализацию следующим образом:

P.S. подобным образом инициализировать строки не стоит, здесь так сделано только для того, чтобы упростить код.

Указатели на поля структуры и на вложенные структуры

Указатели на поля структуры определяются также, как и обычные указатели. Указатели на вложенные структуры возможны только тогда, когда структура определена. Немного переделаем предыдущий пример: «деанонимизируем» вложенную безымянную структуру и возьмём указатели на поля структуры Model:

Как уже говорилось ранее, в си, даже если у двух структур совпадают поля, но структуры имеют разные имена, то их нельзя приводить к одному типу. Поэтому приходится избавляться от анонимных вложенных структур, если на них нужно взять указатель. Можно попытаться взять указатель типа char* на поле структуры, но нет гарантии, что поля будут расположены непрерывно.

Примеры

1. Стек, реализованный с помощью структуры «Узел», которая хранит значение (в нашем примере типа int) и указатель на следующий узел. Это неэффективная реализация, которая требует удаления и выделения памяти под узел при каждом вызове операции push и pop.

2. Реализуем структуру — массив, и некоторые операции для работы с массивами. Тип массива зададим макроподстановкой.

3. Структура Линия, состоит из двух структур точек. Для краткости реализуем только пару операций

Обратите внимание на операции создания и копирования линии. Обязательно нужно копировать содержимое, иначе при изменении или удалении объектов, которые мы получили в качестве аргументов, наша линия также изменится. Если структура содержит другие структуры в качестве полей, то необходимо проводить копирование содержимого всех полей. Глубокое копирование позволяет избежать неявных зависимостей.

4. Структура комплексное число и функции для работы с ней.

Структуры — введение в объектно-ориентированное программирование

Раньше для хранения данных использовались простые типы данных: числа, строки и т.д. Тем не менее, многие объекты, которые возникают в программировании, нельзя охарактеризовать только одной числовой или строковой величиной. Например, точка на плоскости задается парой действительных чисел (x, y), а данные о человеке можно задавать при помощи нескольких строк (фамилии, имени, отчества) и числового параметра: года рождения.

Читать еще:  Как изменить номер слайда в powerpoint

Поэтому удобным является использование объектов, объединяющих сразу ряд параметров, каждый из которых может фигурировать, как отдельная переменная.

Для этого используются специальные типы данных, которые в языке C называются структурами, а в языке C++ – классами. Например, структура Point , задающая точку на плоскости и содержащая два действительных числа x и y может быть задана следующим образом:

Переменные x и y , входящие в структуру Point , называются полями структуры. Определение структуры дается вне всех функций (и, обычно делается перед объявлением всех функций). Определение структуры обязательно завершается точкой с запятой.

После этого мы можем работать с Point , как с новым типом данных, содержащим два поля: x и y . Примеры создания переменной и массива переменных типа Point :

Чтобы обратиться к полю какой-либо структуры, используется оператор «точка». Его левый операнд – идентификатор переменной типа структура, правый операнд – имя поля. Например, P.x или Arr[i].y .

Например, считать координаты точки, сохранить их в переменной P и вывести на экран расстояние от начала координат до этой точки можно следующим образом:

По сути, величины P.x и P.y являются независимыми переменными, скомбинированными в один объект. С этим объектом можно работать, как с единым целым, например, можно выполнять присваивания вроде Arr[i]=P , можно сохранить набор точек в одном массиве и т.д.

Аналогично, можно определить структуру типа Person для хранения информации о человеке:

Теперь можем работать с данными типа Person :

Полями структур могут быть произвольные типы данных. Можно, например, создать структуру, полями которой будут массивы или другие структуры.

Например, пусть мы хотим определить структуру Circle для определения окружности. Окружность задается центром и радиусом. Радиус – это действительное число (поле Radius типа double ), а центр – это, конечно же, точка, то есть поле Center имеет тип Point . Получили:

Дальше с такими «вложенными» структурами можно работать так:

Упражнения на проектирование структуры “Point”

Создайте структуру Point , определите для нее конструктор, необходимые арифметические операции, вывод на экран. У структуры Point два поля: x и y .

A: Самая дальняя точка

Программа получает на вход число N, далее координаты N точек. Выведите координаты точки, наиболее удаленной от начала координат.

Для решения этой задачи напишите метод dist , который возвращает расстояние от точки до начала координат.

Структуры (Struct) в C++

В сегодняшнем уроке мы рассмотрим структуры в C++ (Structs). Структуры позволяют определить свой собственный тип данных. В предыдущих урокам мы сталкивались только со стандартными типами данных языка С++: char, float, int. Когда мы начнём рассматривать WinAPI, то увидим, что Microsoft использовала огромное количество структур при написании Windows.

В структурах можно определить несколько переменных для моделирования какого-либо сложного понятия. Например, в нашей программе есть множество юнитов. При этом каждый должен обладать свойствами: размер, сила и скорость. Вот так мы можем описать это в C++ без структур:

Для описания 10 юнитов с тремя свойствами нам потребуется три массива. При этом отдельные свойства юнитов — это простые целые числа. Для доступа к свойствам определённого юнита нам придётся обращаться к разным массивам. Это не слишком удобно. Давайте посмотрим, как можно описать юнит в С++ с помощью структур:

Структуры C++

Структуры С++ позволяют построить более адекватную модель сложной (сложнее чем простое число или строка) сущности. Когда мы создаём модель, мы стараемся описать самые важные свойства объекта из реального мира (или абстрактного понятия). Так как в наших примерах мы рассматриваем создание игр, то и примеры будем приводить из этой области. В данном коде мы пытаемся описать единицу (юнит) из какой-то абстрактной игры. В данном случае юнит обладает тремя свойствами — вы сами определяете, что должно быть в структуре.

Структура определяется с помощью ключевого слово struct, после которого идёт имя структуры. Имя может быть любым (стандартный идентификатор C++). В дальнейших уроках все имена структур будут начинаться с заглавной буквы. В WinAPI имена всех структур пишутся в верхнем регистре: RECT, POINT, SIZE и т.д. В фигурных скобках мы описываем разные свойства структуры с помощью объявления переменных. В данном случае, структура Unit будет иметь три свойства: size, speed, strength. Эти переменные называются членами, полями или свойствами структуры. Обратите внимание на точку с запятой после закрывающей фигурной скобки — она обязательна.

Структуры в C++ пришли из языка C. При этом С++ структуры имеют некоторые отличия от оригинала. В следующем уроке мы начнём рассматривать классы и увидим чем структуры в С отличаются от структур в C++.

С++ структуры в памяти

В памяти поля структур располагаются последовательно. Поля size, speed, strength будут расположены рядом. Между ними не будет никаких других данных. Вот как может выглядеть переменная типа Unit в памяти:

Последовательное расположение полей структуры в памяти позволяет хранить структурные переменные в массивах и легко копировать их.

Здесь же я хочу обратить внимание на концептуальную разницу между массивами и структурами. И то и другое для компьютера всего лишь множество переменных. В случае массива эти переменные должны быть одного типа, а структуры необходимы для описания более сложных понятий.

Пользовательский тип данных

В последней строке мы создаём массив из десяти структурных переменных. Теперь осталось узнать, как получить доступ к свойствам. Также, мы можем сразу задать значения полям структурных переменных:

Значения в фигурных скобках инициализируют поля структурных переменных в том же порядке, в каком поля идут в определении структуры.

Ещё раз повторю, так как это важно: для компьютера это всего лишь числа не имеющие никакого значения. Значение этим числам придаём мы. Мы строим модель какого-то понятия (юнита в данном случае). И мы сами интерпретируем эти значения. Глядя на последний массив мы можем сказать про наши юниты следующее: первый — середнячок, у него все параметры средние; второй — маленький, быстрый, но слабый; последний — большой, медленный, но сильный. Это всего-лишь данные. Когда мы познакомимся с графическим выводом, мы сможем наглядно преподнести эти данные пользователю.

Доступ к полям структурных переменных

Мы можем прочитать и изменить отдельные поля с помощью оператора доступа к члену (member selection operator или member access operator) — точки:

Сначала мы указываем имя структурной переменной, потом точку, затем имя поля к которому мы хотим получить доступ.

Для структурных переменных, созданных динамически, используется оператор непрямого доступа ->.

В отличии от указателей на обычные типы, поля структурных переменных разыменовываются через стрелочку, а не через звёздочку. В остальном их поведение одинаково.

Заключение

В данном уроке мы рассмотрели структуры в C++. В следующем мы сделаем логичный шаг и объединим в одной сущности не только переменные, но и функции: наши модели понятий будут обладать не только свойствами, но и поведением — мы начнём рассматривать классы.

Классы обертки для структур RECT POINT и SIZE

Операционная система дает возможность программам определять размер окна, размер клиентской области, позицию указателя мыши на экране и многое другое, используя структуры RECT, POINT и SIZE. Но эти структуры довольно неудобно использовать. Эта статья расскажет вам, как реализовать классы, которые позволят использовать все возможности вышеприведенных структур, и упростят использование функций связанных с ними. Достоинство этих классов, заключается в том, что существует возможность их использования в любых Win32 приложениях, без подключения каких либо других файлов. Для того чтобы использовать эти классы в своих приложениях достаточно подключить заголовочный файл требуемого класса в файл реализации, использующий эти классы.

Читать еще:  System center endpoint protection

Для начала определимся с названиями. Дадим им имена TRect, TPoint и TSize. Имена обусловлены тем, что эти классы будут являться производными от структур RECT POINT и SIZE соответственно. Каждый из этих классов унаследуют следующие целочисленные переменные-члены:
TRect – left, top, right, bottom от структуры RECT.
TPoint – x,y от структуры POINT.
TSize – cx,cy от структуры SIZE.

Функции арифметики всех трех классов будут использовать соответствующие функции Win32. Во всех классах, декларации структуры, оберткой которой является класс, будут помещены в защищенный раздел класса.
Это предотвратит нежелательный доступ непосредственно к данным самой структуры. Доступ будет реализован средствами класса.

Члены структуры SIZE имеют тип LONG. По этому большинство функций-членов класса будут оперировать именно с этим типом данных.
Как было сказано выше, декларация структуры будет помещена в защищенный раздел класса.
class TSize
<
public :
protected :
SIZE m_Size;
>;
Добавим в этот класс конструктор и деструктор. Деструктор в конкретном случае будет виртуальным, и ничего полезного делать не будет. Точнее он вообще не будет ничего делать, как и в оставшихся двух классах.
Конструкторов же у этого класса будет два, как , впрочем, и у TRect и TPoint.
Первый конструктор будет конструктором по умолчанию, предназначенным для первоначальной инициализации класса и заполнения всей структуры нулями. Второй конструктор применяется только в том случае, если при декларации класса, в конструктор переданы аргументы. В этом случае параметры внутренней структуры SIZE инициализируются переданными значениями.
Пока ничего полезного этот класс не делает.
Добавим ему функциональности, которой не хватает структуре SIZE.
Добавим функцию реализующую сравнение объекта с существующей структурой SIZE.

inline BOOL IsEqual( const SIZE & sz ) const < return ( sz . cx == m_Size . cx && sz . cy == m_Size . cy ); >Что мы здесь делаем? Сравниваем члены внутренней переменной SIZE класса с переданной переменной sz.

Обеспечим класс функциями, позволяющими к переменным внутренней структуры добавлять или вычитать некоторые значения: // Добавляет переданные размеры к существующим inline void Add( int cx, int cy ) < m_Size . cx += cx; m_Size . cy += cy; >inline void Add( const SIZE & sz ) < m_Size . cx += sz . cx; m_Size . cy += sz . cy; >inline void AddCX( int cx ) < m_Size . cx += cx; >inline void AddCY( int cy ) < m_Size . cy += cy; >// Вычитает переданные размеры из существующих inline void Subtract( int cx, int cy ) < m_Size . cx -= cx; m_Size . cy -= cy; >inline void Subtract( const SIZE & sz ) < m_Size . cx -= sz . cx; m_Size . cy -= sz . cy; >inline void SubtractCX( int cx ) < m_Size . cx -= cx; >inline void SubtractCY( int cy ) < m_Size . cy -= cy; >Все эти функции, в принципе, делают то же самое, что и функция IsEqual. Только функция IsEqual сравнивает члены внутренней структуры с членами переданной, а эти или добавляют или вычитают переданные параметры из членов внутренней структуры. Так же введем функции, позволяющие получить значения членов внутренней структуры SIZE. // Возвращает сx или сy координату. inline int & CX() const < return ( int & )m_Size . cx; >inline int & CY() const < return ( int & )m_Size . cy; >Эти функции позволяют, и получать значения внутренней переменной и изменять их.
Реализуем четыре базовых вида перегруженных операторов, применимых только к структуре SIZE. Операторы сложения, вычитания, присваивания, сравнения и преобразования. // Перегруженные операторы преобразования. inline operator SIZE * () < return & m_Size; >inline operator SIZE() const < return m_Size; >// Перегруженные операторы присваивания inline void operator = ( const SIZE & sz ) < m_Size = sz; >inline void operator = ( LPSIZE sz ) < m_Size = * sz; >// Перегруженные операторы сравнения inline BOOL operator == ( const SIZE & sz ) const < return IsEqual( sz ); >inline BOOL operator != ( const SIZE & sz ) const < return ! IsEqual( sz ); >// Перегруженные операторы сложения inline void operator += ( const SIZE & sz ) < Add( sz ); >inline TSize operator + ( const SIZE & sz ) const < TSize szTmp( * this ); szTmp += sz; return szTmp; >// Перегруженные операторы вычитания inline void operator -= ( const SIZE & sz ) < Subtract( sz ); >inline TSize operator — ( const SIZE & sz ) const < TSize szTmp( * this ); szTmp -= sz; return szTmp; >Все эти операторы очень пригодятся для упрощения написания программы. Они позволяют производить следующие манипуляции с этим классом:

  • Приводить класс TSize к типу SIZE* или SIZE
  • Сравнивать класс TSize со структурой SIZE
  • Приравнивать класс TSize к SIZE* или SIZE
  • Складывать класс TSize со структурой SIZE
  • Вычитать класс TSize и структуру SIZE друг из друга

Класс TPoint

Класс TPoint по реализации ничем не отличается от класса TSize, по этому детально рассмотрен не будет. Все названия функций идентичны. Отличие состоит в том, что класс TSize манипулирует структурой SIZE, а класс TPoint структурой POINT.

Этот класс представляет интерес по следующим причинам. Практически все функции, связанные с определением и изменением размеров окон, манипулируют структурой RECT в той или иной мере. Да и функций, применяющих эту структуру довольно много.
Как и два предыдущих класса, этот класс имеет в защищенном разделе декларацию структуры. Отличие состоит в том, что в этом классе, объявлена структура RECT. Конструкторы и деструкторы те же, но манипулируют структурой RECT. Также этот класс имеет все функции для работы с прямоугольниками:

CopyRect Копирует координаты одного прямоугольника в другой
EqualRect Определяет, являются ли два указанных прямоугольника равными, сравнивая координаты их левых верхних и нижних правых углов.
InflateRect Увеличивает или уменьшает ширину и высоту указанного прямоугольника.
IntersectRect Вычисляет пересечение двух исходных прямоугольников и помещает координаты пересечения прямоугольников в прямоугольник назначения
IsRectEmpty Определяет, является ли указанный прямоугольник пустым.
OffsetRect Перемещает указанный прямоугольник на указанное смещение
PtInRect Определяет, находится ли указанная точка в пределах указанного прямоугольника.
SetRect Устанавливает координаты указанного прямоугольника.
SetRectEmpty Создает пустой прямоугольник, в котором все координаты установлены на ноль.
SubtractRect Определяет координаты прямоугольника, сформированного путем вычитания одного прямоугольник из другого.
UnionRect Создает объединение двух прямоугольников.

Подробнее обо всех этих функциях вы можете прочитать на этом сайте в разделе MSDN по-русски. Реализацию всех функций вы можете посмотреть в предоставленном ниже листинге.
В заключение хотелось бы добавить несколько слов.
При написании программ очень сильно помогают макросы.
Добавим макросы, позволяющие упростить декларацию этих классов:
Для класса TPoint:
Для класса TSize: Для класса TRect: Ниже приведен листинг всех классов.

Ссылка на основную публикацию
Adblock
detector