Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Иерархия классов

Читайте также:
  1. Quot;Орудие классового господства
  2. VIII. ИЕРАРХИЯ ЭТНИЧЕСКИХ ОБЩНОСТЕЙ.
  3. Аристотель о классовом расслоении общества
  4. Внеклассное мероприятие для 3-4 классов.
  5. Вы прогневали своего учителя. Обратитесь к нему для получения наказания. Класс задания: обычное классовое.
  6. Вычитание классов
  7. ГЛАВА I КЛАССОВОЕ ОБЩЕСТВО И ГОСУДАРСТВО

Производный класс сам в свою очередь может быть базовым классом:

class employee { /*... */ };

class manager: public employee { /*... */ };

class director: public manager { /*... */ };

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

class temporary { /*... */ };

class secretary: public employee { /*... */ };

class tsec

: public temporary, public secretary { /*... */ };

class consultant

: public temporary, public manager { /*... */ };

 

85.

Понятие объекта и класса.

Классы C++ являются основой объектно-ориентированного программирования.

В известном смысле объект представляет собой сущность, с которой ваши программы выполняют разные операции.

Программы на C++ представляют объекты посредством классов.

Класс, подобно структуре, содержит элементы. Элементы класса могут хранить информацию (данные) или быть функциями (методами), которые оперируют этими данными.

Каждый класс имеет уникальное имя.

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

Для обращения к элементам класса (как к данным, так и к функциям) ваши программы используют оператор точку.

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

Класс позволяет вашим программам группировать данные и функции которые выполняют операции над этими данными. Большинство книг и статей об объектно-ориентированном программировании называют функции класса методами. Подобно структуре, класс C++ должен иметь уникальное имя, за которым следует открывающая фигурная скобка, один или несколько элементов и закрывающая фигурная скобка:

class class_name

{

int data_member; // Элемент данных

void show_member(int); // Функция-элемент

};

После определения класса вы можете объявлять переменные типа этого класса (называемые объектами), как показано ниже:

class_name object_one, object_two, object_three;

Следующее определение создает класс employee, который содержит определения данных и метода:

class employee

{

public:

char name[64];

long employee_id;

float salary;

void show_employee(void)

{

cout << "Имя: " << name << endl;

cout << "Номер служащего: " << employee_id << endl;

cout << "Оклад: " << salary << endl;

};

};

В данном случае класс содержит три переменные и одну функцию-элемент. Обратите внимание на использование метки public внутри определения класса. Как вы узнаете из урока 22, элементы класса могут быть частными (private) или общими {public), от чего зависит, как ваши программы обращаются к элементам класса. В данном случае все элементы являются общими, это означает, что программа может обращаться к любому элементу, используя оператор точку. После определения класса внутри вашей программы вы можете объявить объекты (переменные) типа этого класса, как показано ниже:

————————————————————— Имя класса

employee worker, boss, secretary; //--------->Переменные класса (объекты)

Представление об объектах

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

86.

Включение в данные объекта информации о методах их обработки

Методы класса

Классы C++ позволяют вашим программам группировать данные объекта и функции объекта (методы), которые оперируют с этими данными, в одной переменной. У вас есть две возможности определения методов объекта. Первая состоит в том, что вы можете включить весь код функции внутрь определения класса. Несмотря на то что включение кода метода в определение класса может представляться удобным, однако, когда классы становятся сложнее и включают несколько методов, операторы функций могут вносить беспорядок в определение классов. Таким образом, многие программы определяют операторы функции вне класса. В определение класса программа должна включать прототип функции, который указывает имя функции, тип возвращаемого значения и типы параметров.

Для определения функции вне определения класса ваша программа должна предварять определение функции именем класса и оператором глобального разрешения, как показано ниже:

return_type class_name::function_name(parameters)

{ // Операторы }

 

88.

Объявление класса: private, protected, public элементы класса

Класс в языке C++ создаётся следующим образом:

class MyClass: ParentClass // ParentClass — класс-предок, если таковой имеется

{

public:

// элементы в этой секции доступны из любой части программы

protected:

// элементы в этой секции доступны из класса и его потомков

private:

// элементы в этой секции доступны только из класса; это область доступа по умолчанию

MyClass() // конструктор

~MyClass() // деструктор

}

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

MyClass myinstance;

Обращение к членам класса:

myinstance.classmember

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

private (закрытый, внутренний член класса) — обращения к члену допускаются только из методов того класса, в котором этот член определён. Любые наследники класса уже не смогут получить доступ к этому члену. Наследование по типу private запрещает доступ из дочернего класса ко всем членам родительского класса, включая даже public-члены (С++);

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

public (открытый член класса) — обращения к члену допускаются из любого кода. Наследование по типу public не меняет модификаторов родительского класса (С++);

 

89.

Интерфейс класса. Свойство защищенности интерфейса класса

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

C++ поддерживает множественное наследование и абстрактные классы, поэтому, как уже упоминалось выше, отдельная синтаксическая конструкция для интерфейсов в этом языке не нужна. Интерфейсы определяются при помощи абстрактных классов, а реализация интерфейса производится путём наследования этих классов.

Пример определения интерфейса:

/**

* interface.Openable.hpp

*

*/

#ifndef INTERFACE_OPENABLE_HPP

#define INTERFACE_OPENABLE_HPP

// Класс интерфейса iOpenable. Определяет возможность открытия/закрытия чего либо.

class iOpenable

{

public:

virtual ~iOpenable(){}

virtual void open()=0;

virtual void close()=0;

};

#endif

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

90.

Доступ к глобальным и локальным данным, область видимости для идентификаторов, объявленных внутри класса.

Локальные переменные представляют собой переменные, объявленные внутри функции.

Локальные переменные известны только той функции, внутри которой они объявлены.

Несколько функций могут использовать одно и то же имя для локальной переменной без каких-либо конфликтов.

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

Чтобы объявить глобальную переменную, объявите переменную в начале вашего исходного файла вне какой-либо функции.

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

ОБЪЯВЛЕНИЕ ЛОКАЛЬНЫХ ПЕРЕМЕННЫХ

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

void some_function(void)

{

int count;

float result;

}

О конфликте имен

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

О локальных переменных

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

ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ

Как вы уже знаете, локальная переменная объявляется и известна только в определенной функции. В дополнение к локальным переменным C++ позволяет вашим программам объявлять глобальные переменные, которые известны на протяжении всей программы (глобально для всех функций). Чтобы объявить глобальную переменную, следует просто поместить объявление переменной в начало вашей программы вне какой-либо функции:

int some_global_variable; ---> Объявление глобальной переменной

void main(void)

{

// Здесь должны быть операторы программы

}

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

Если имена глобальных и локальных переменных конфликтуют

По мере возможности следует избегать использования в программах глобальных переменных. Однако если ваша программа должна использовать глобальную переменную, то может случиться, что имя глобальной переменной конфликтует с именем локальной переменной. При возникновении такого конфликта C++ предоставляет приоритет локальной переменной. Другими словами, программа предполагает, что в случае конфликта каждая ссылка на имя соответствует локальной переменной.

Однако могут быть ситуации, когда вам необходимо обратиться к глобальной переменной, чье имя конфликтует с именем локальной переменной. В таких случаях ваши программы могут использовать глобальный оператор разрешения С++ (::), если вы хотите использовать глобальную переменную.

О глобальных переменных

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

Представление об области видимости переменных

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

91.

Для ограничения уровня доступа к данным и функциям-членам класса в С++ существуют три ключевых слова private: (частный), protected: (защищенный), public: (общедоступный), задающие разделы поступа в классе. Каждый раздел в классе начинается с одного из приведенных слов. Если ни одно из ключевых слов не использовалось, то все объявления в классе считаются частными. Разделы с разными привилегиями доступа могут появлятся в любом порядке и в любом колличестве. Рассмотрим пример.

class Example {

int x1; // частные по умолчанию

int f1(void);

protected:

int x2; // защищенные

int f2(void);

private:

int x3; // опять частные

int f3(void);

public:

int x4; // общедоступные

inf f4(void);

};

Друг или функция-член производного класса имеет доступ к защищенному статическому члену базового класса. Друг или функция-член производногокласса могут получить доступ к защищенному нестатическому члену одного из своих базовых классов только через указатель, ссылку или объект производного класса (или любого класса, являющегося производным по отношению к нему). Рассмотрим пример:

class B {

protected:

int i;

};

class D1: public B {

};

class D2: public B {

friend void fr(B*, D1*, D2*);

void mem(B*, D1*);

};

void fr(B* pb, D1* p1, D2* p2)

{

pb->i = 1; // недопустимо

p1->i = 2; // недопустимо

p2->i = 3; // нормально (обращение через D2)

}

void D2::mem(B* pb, D1* p1)

{

pb->i = 1; // недопустимо

p1->i = 2; // недопустимо

i = 3; // нормально (обращение через this)

}

void g(B* pb, D1* p1, D2* p2)

{

pb->i = 1; // недопустимо

p1->i = 2; // недопустимо

p2->i = 3; // недопустимо

}

 

92.

Объекты класса как члены

Рассмотрим пример:

class classdef {

table members;

int no_of_members;

//...

classdef(int size);

~classdef();

};

Цель этого определения, очевидно, в том, чтобы classdef содержал член, являющийся таблицей размером size, но есть сложность: надо обеспечить вызов конструктора table::table() с параметром size. Это можно сделать, например, так:

classdef::classdef(int size)

:members(size)

{

no_of_members = size;

//...

}

Параметр для конструктора члена (т.е. для table::table()) указывается в определении (но не в описании) конструктора класса, содержащего член (т.е. в определении classdef::classdef()). Конструктор для члена будет вызываться до выполнения тела того конструктора, который задает для него список параметров.

Аналогично можно задать параметры для конструкторов других членов (если есть еще другие члены):

class classdef {

table members;

table friends;

int no_of_members;

//...

classdef(int size);

~classdef();

};

Списки параметров для членов отделяются друг от друга запятыми (а не двоеточиями), а список инициализаторов для членов можно задавать в произвольном порядке:

classdef::classdef(int size)

: friends(size), members(size), no_of_members(size)

{

//...

}

Конструкторы вызываются в том порядке, в котором они заданы в описании класса.

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

Если конструктору члена не требуется параметров, то и не нужно задавать никаких списков параметров. Так, поскольку конструктор table::table() был определен со стандартным значением параметра, равным 15, достаточно такого определения:

classdef::classdef(int size)

: members(size), no_of_members(size)

{

//...

}

Тогда размер таблицы friends будет равен 15.

Если уничтожается объект класса, который сам содержит объекты класса (например, classdef), то вначале выполняется тело деструктора объемлющего класса, а затем деструкторы членов в порядке, обратном их описанию.

Рассмотрим вместо вхождения объектов класса в качестве членов традиционное альтернативное ему решение: иметь в классе указатели на члены и инициализировать члены в конструкторе:

class classdef {

table* members;

table* friends;

int no_of_members;

//...

};

 

classdef::classdef(int size)

{

members = new table(size);

friends = new table; // используется стандартный

// размер table

no_of_members = size;

//...

}

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

classdef::~classdef()

{

//...

delete members;

delete friends;

}

Такие отдельно создаваемые объекты могут оказаться полезными, но учтите, что members и friends указывают на независимые от них объекты, каждый из которых надо явно размещать и удалять. Кроме того, указатель и объект в свободной памяти суммарно занимают больше места, чем объект-член.

93.

Обычно каждый объект класса имеет свою собственную копию всех данных-элементов класса. Но в определенных случаях во всех объектах класса должна фигурировать только одна копия некоторых данных-элементов для всех объектов класса. Для этих и других целей используются статические данные-элементы, которые содержат информацию «для всего класса». Объявление статических элементов начинается с ключевого слова static.Хотя может показаться, что статические элементы данные похожи на глобальные переменные, тем не менее они имеют областью действия класс. Статические элементы могут быть открытыми, закрытыми или защищенными (protected). Статическим данным-элементам можно задать начальные значения один (и только один) раз в области действия файл. Доступ к открытым статическим элементам класса возможен посредством любого объекта класса или посредством имени класса, с помощью бинарной операции разрешения области действия. Закрытые и защищенные статические элементы класса должны быть доступны открытым функциям-элементам этого класса или друзьям класса. Статические элементы класса существуют даже тогда, когда не существует никаких объектов этого класса. Чтобы в этом случае обеспечить доступ к открытому статическому элементу, просто поставьте перед элементом данных имя класса и бинарную операцию разрешения области действия. Для обеспечения доступа в указанном случае к закрытому или защищенному элементу класса должна быть предусмотрена открытая статическая функция-элемент, которая должна вызываться с добавлением перед ее именем имени класса и бинарной операции разрешения области действия.

94.

Ссылки

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

Объявление вида:

<Type> & <Name>

где <Type> — тип и <Name> — идентификатор, указывают идентификатор, чьим типом является ссылка на <Type>.

Примеры:

int A = 5;

int& rA = A;

extern int& rB;

int& foo ();

void bar (int& rP);

class MyClass { int& m_b; /*... */ };

int funcX() { return 42; }; int (&xFunc)() = funcX;

Здесь, rA и rB являются типами «ссылок на int», foo() — функция, возвращающая ссылку на int, bar() — функция с ссылкой в качестве параметра, которая ссылается на int, MyClass — класс (class) с членом, ссылающимся на int, funcX() — функция, возвращающая int, xFunc() — псевдоним для funcX.

Типы, относящиеся к «ссылка на <Type>», иногда называются ссылочными типами. Идентификаторы ссылочного типа называются ссылочными переменными. Вызывать их переменную фактически будет неправильно (показано дальше).


Дата добавления: 2015-07-26; просмотров: 83 | Нарушение авторских прав


Читайте в этой же книге: Функция gets(). 3 страница | Функция gets(). 4 страница | Функция gets(). 5 страница | Функция gets(). 6 страница | Функция gets(). 7 страница | Целый тип данных | Указатели | Инициализация данных | Структуры | Синтаксис описания шаблона |
<== предыдущая страница | следующая страница ==>
Полиморфизм| Связь с указателями

mybiblioteka.su - 2015-2024 год. (0.037 сек.)