Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

информатика теория

.pdf
Скачиваний:
36
Добавлен:
03.06.2015
Размер:
827.15 Кб
Скачать

В результате, вы сами, или кто-то ещё, может расширять и модифицировать классы с использованием уже готовых их частей. Естественно, если вы используете что-то с модификатором protected (чаще всего это вызов или переопределение методов родительского класса), то вы или сами это всё наваяли, или «расписываетесь» в том, что вашей квалификации и степени разумности хватает для подобных действий. Напортачили? Сами виноваты.

Модификатор «public»: кому бы дать?

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

Обратите внимание на предыдущий абзац ещё раз. Да не на публичный дом! А на взаимоотношения «класс-объект», выделенные курсивом. Если увидите, что из чего проистекает, ваша речь по этому вопросу станет гораздо грамотнее и вы перестанете раздражать общественность сентенциями вроде «выложил свой объект в сеть» и «создал в программе новый класс».

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

Класс: Автомобиль {

...

публичная переменная марка: Строка; публичная переменная модель: Строка;

...

публичная функция заголовокДляПрайсЛиста() {

вернуть марка + " " + модель;

}

}

Класс ДругойАвтомобиль наследует Автомобиль {

...

публичная функция левыйЗаголовок() { вернуть модель + марка +" левый текст";

}

...

}

переменная авто = cоздать_объект_класса "Автомобиль"; переменная авто2 = cоздать_объект_класса "ДругойАвтомобиль";

напечатать авто->заголовокДляПрайсЛиста(); напечатать авто2->марка;

Обязательно изучайте конкретные реализации

При освоении нового для вас языка программирования, обязательно сразу лезьте читать про особенности реализации ООП в целом и как сделано управление видимостью private- protected-public. Везде свои особенности. Например, в Java сами классы могут объединяться в пакеты классов и быть приватными или защищенными внутри пакетов. В итоге получаем дополнительный уровень доступа, дающий, с одной стороны, более широкие возможности по структуризации программы, а с другой стороны — дополнительные оттенки проектирования, которые надо учитывать.

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

Интерфейс

Интерфейсы, как и классы, определяют набор свойств, методов и событий. Но, в отличие от классов, интерфейсы не предоставляют реализацию. Они реализуются классами, но определяются как отдельные от классов сущности. Интерфейс представляет собой контракт, в котором класс, реализующий интерфейс, должен реализовывать каждый аспект этого интерфейса в точном соответствии с его определением.

Тема довольно избита, однако, я всё-таки решил начать с неё. Думаю, новичкам будет полезно.

Итак, public, private и protected — это модификаторы доступа, а не видимости, как ошибочно думают некоторые. Private

члены видны снаружи класса, но не доступны.

Теперь кратко, кому какой доступ они предоставляют.

Public — доступ открыт всем, кто видит определение данного класса.

Private — доступ открыт самому классу (т.е. функциям-членам данного класса) и друзьям (friend) данного класса, как функциям, так и классам.

Protected — доступ открыт классам, производным от данного.

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class some {

friend void f(some&); public:

int a_; protected: int b_;

private: int c_;

};

void f(some& obj) { obj.a_ = 0; // OK obj.b_ = 0; // OK obj.c_ = 0; // OK

}

void g(some& obj) { obj.a_ = 0; // OK

obj.b_ = 0; // compile time error obj.c_ = 0; // compile time error

}

class derived : public some { derived() {

a_ = 0; // OK b_ = 0; // OK

c_ = 0; // compile time error

}

};

В C++ существует public-наследование, private-наследование и protected-наследование. В зависимости от того, какой тип

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

этом изменении.

 

 

 

Исходный модификатор доступа

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public

 

 

private

 

protected

 

 

 

 

 

 

 

 

 

 

public-наследование

 

public

 

 

private

 

 

protected

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

private-

 

private

 

 

private

 

 

private

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

наследование

 

 

 

protected-

 

 

 

наследование

protected

private

protected

Следует добавить, что производный класс может изменить модификатор доступа с protected на public, разместив using

объявление в соответствующей секции класса:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class some { public:

int a; protected:

int b; private:

int c; };

class derived : public some { public:

using some::b; };

void f(derived& obj) { obj.b = 0; // OK

}

Напоследок приведу несколько приёмов, с помощью которых можно «достучаться» до закрытых функций или

данных. Допустим, у нас есть класс some и нам нужно обнулить закрытую переменную c:

Модифицировать определение класса, добавив друга (функцию или класс)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class some {

friend class some_friend; public:

int a; protected:

int b; private:

int c; };

class some_friend { public:

static void hack(some& obj) {

obj.c = 0;

}

};

Воспользоваться препроцессором:

1

2

3

4

5

6

#define private public

class some { public:

int a; protected:

int b; private:

7

8

9

10

11

12

13

14

int c; };

void hack(some& obj) { obj.c = 0;

}

Создать класс с таким же расположением в памяти и воспользоваться reinterpret_cast для преобразования указателей:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

class some { public:

int a; protected:

int b; private:

int c; };

class hack_some { public:

int a; int b;

int c; };

void h(some& obj) { reinterpret_cast<hack_some*>(&obj)->c = 0;

}

Если у «взламываемого» класса есть шаблонная функция, можно её специализировать своим типом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class some { public:

int a;

template<class T> void func(void) { a = b + c;

}

protected:

int b; private:

int c; };

class hack_template_param{};

template<>

void some::func<hack_template_param>(void) { c = 0;

}

void hack(void) { some o;

o.func<hack_template_param>();

19 };

20

21

22

23

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

Drawable представление текстуры, со своими преобразований, цвета и

т.д. Подробнее ...

#include < Sprite.hpp >

Наследование схема SF :: Sprite:

Открытые члены

Спрайт ()

Конструктор по умолчанию.

Спрайт (строительства Текстура и текстуры)

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

Спрайт (строительства Текстура и текстуры, строительства IntRect и прямоугольник)

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

пустота SetTexture (строительства Текстура и текстуры, BOOL resetRect = ложь)

Изменить исходный текстуры спрайта.

пустота setTextureRect (строительства IntRect и прямоугольник)

Установите суб-прямоугольник текстурой, которая будет отображать спрайт.

пустота SetColor (строительства Цвет & цвет)

Устанавливает глобальную цвет спрайта.

строительства Текстура * getTexture () строительства

Получить исходный текстуры спрайта.

строительства IntRect & getTextureRect () строительства

Получить суб-прямоугольник текстуры, отображаемой спрайта.

строительства Цвет & GetColor () строительства

Получить глобального цвет спрайта.

FloatRect getLocalBounds () строительства

Получить местный ограничивающий прямоугольник объекта.

FloatRect getGlobalBounds () строительства

Получить глобального ограничивающий прямоугольник объекта.

пустота SetPosition (поплавок х, поплавок у)

установить позицию объекта

пустота SetPosition (строительства Vector2f и должность)

установить позицию объекта

пустота setRotation (угол с плавающей точкой)

установить ориентацию объекта

пустота setScale (плавать, плавать factorX завод)

установить масштабные коэффициенты объекта

пустота setScale (строительства Vector2f и факторы)

установить масштабные коэффициенты объекта

пустота setOrigin (поплавок х, поплавок у)

установки локального происхождение объекта

пустота setOrigin (строительства Vector2f и происхождения)

установки локального происхождение объекта

строительства Vector2f & GetPosition () строительства

получить позицию объекта

поплавок getRotation () строительства

получить ориентацию объекта

строительства Vector2f & getScale () строительства

получить текущий масштаб объекта

строительства Vector2f & getOrigin () строительства

получить местное происхождение объекта

пустота двигаться (плавать OffsetX, плавать

OffsetY)

Перемещение объекта по заданному

смещению.

пустота двигаться (строительства Vector2f и смещение)

Перемещение объекта по заданному смещению.

пустота вращаться (угол с плавающей точкой)

Поверните объект.

пустота Шкала (плавать factorX, поплавок завод)

Масштаб объекта.

пустота Шкала (строительства Vector2f и фактор)

Масштаб объекта.

строительства Transform & getTransform () строительства

получить комбинированный преобразование объекта

строительства Transform & getInverseTransform () строительства

получить обратный сочетании преобразование объекта