Главная страница
Финансы
Экономика
Математика
Начальные классы
Информатика
Биология
Медицина
Сельское хозяйство
Ветеринария
Вычислительная техника
Дошкольное образование
Логика
Этика
Религия
Философия
Воспитательная работа
История
Физика
Политология
Социология
Языкознание
Языки
Право
Юриспруденция
Русский язык и литература
Строительство
Промышленность
Энергетика
Другое
Доп
образование
Связь
Электротехника
Автоматика
Физкультура
Технология
Классному руководителю
Химия
Геология
Иностранные языки
Логопедия
Искусство
Экология
Культура
География
ИЗО, МХК
Казахский язык и лит
Директору, завучу
Школьному психологу
Обществознание
Социальному педагогу
Языки народов РФ
ОБЖ
Музыка
Механика
Украинский язык
Астрономия
Психология

Глава 12 Классы_Объекты_Массивы объектов 2015. Классы и объекты. Массивы объектов. Определение класса, объекта спецификаторы доступа к членам класса


НазваниеКлассы и объекты. Массивы объектов. Определение класса, объекта спецификаторы доступа к членам класса
АнкорГлава 12 Классы_Объекты_Массивы объектов 2015.doc
Дата19.02.2018
Размер108 Kb.
Формат файлаdoc
Имя файлаГлава 12 Классы_Объекты_Массивы объектов 2015.doc
ТипГлава
#12934

ГЛАВА 12. КЛАССЫ И ОБЪЕКТЫ. МАССИВЫ ОБЪЕКТОВ.


Определение класса, объекта

  • спецификаторы доступа к членам класса

  • определение функций класса

  • создание объектов, доступ к членам класса

  • локальные и глобальные объекты

  • присваивание объектов

Конструкторы, деструкторы

  • конструкторы с параметрами

  • конструкторы по умолчанию

  • перегрузка конструкторов

Массивы объектов

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

Всюду в реальном мире нас окружают объекты: люди, животные, растения, здания, самолёты и тому подобные. Каждый объект характеризуется присущими ему свойствами и совершаемыми действиями (поведением). Объекты, обладающие похожими свойствами и поведением, принадлежат к одним и тем же, или похожим классам.

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

Инкапсуляция – это объединение данных и обрабатывающих их функций в одном объекте.

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

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

Определение класса, объекта


Класс представляет собой тип, определяемый пользователем, и в простейшем случае синтаксис его определения имеет вид:

сlass имя_класса{

// члены класса

};

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

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

Определение класса соответствует введению нового типа данных, а определение переменной данного типа – заданию объекта.

Спецификаторы доступа к членам класса


Каждый член класса обладает статусом доступа, для указания которого используются спецификаторы доступа private и public, которые всегда заканчиваются символом двоеточия (:) и могут появляться в определении класса много раз и в любом порядке.

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

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

Набор открытых функций-членов класса представляет открытый интерфейс класса.

class Samp{ // определение класса Samp

int a; // закрытая переменная a

public:

int b; // открытая переменная b

void set(int n); // открытые функции set(), get()

int get();

};

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

Определение функций класса


Функции класса определяются как обычные функции. Но для того чтобы показать, что эти функции принадлежат классу, нужно перед именем функции записать имя класса и операцию разрешения области видимости (::). Данная операция указывает, какой области видимости (т.е. какому классу) принадлежит функция. После заголовка функции располагается тело функции в фигурных скобках. Например, определим функции set() и get() класса Samp следующим образом:

Samp::set(int n){a = n;} // установка переменной a

int Samp::get(){ // чтение переменной a

return a;

}

Функции класса также могут быть определены внутри определения класса. В этом случае они считаются inline-функциями.

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

Создание объектов, доступ к членам класса


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

Samp ob1, ob2;

создаёт объекты ob1 и ob2 класса Samp.

Все объекты класса имеет общие функции, но каждый объект класса

создаёт и поддерживает свои собственные данные.

После создания объекта может возникнуть необходимость в получении доступа к его отдельным элементам. Доступ к открытым данным можно получить напрямую, используя операцию точка (.), например, ob1.b = 1; ob2.b = 2; ob1.set(); или через указатель на этот объект, используя операцию стрелка (–>), например, ob1–>b = 1; ob1->set();

Операторы же вида

ob1.a = 5; ob2.a = 9;

приводят к возникновению ошибок компиляции, так как a закрытая переменная класса и к ней нет прямого доступа. Доступом к закрытым данным можно эффективно управлять с помощью открытых функций класса, называемых функциями доступа. Обычно эти функции называют set() и get(), хотя это и необязательно. Например, изменить закрытые данные класс может позволить своим пользователям с помощью функции доступа set() следующим образом:

ob1.set(5); ob2.set(9); // ob1.a = 9 ob2.a = 5

Если класс хочет позволить читать закрытую переменную класса a, он может обеспечить это с помощью функции чтения get(), например:

ob1.get(); ob2.get(); // чтение переменной a объектов ob1и ob2

// Пример 12.1. Определение класса. Создание и использование

// объектов. Доступ к членам класса.

#include

using namespace std;

class Samp{ // определение класса Samp

int a; // private-переменная a

public: // public-члены

int b;

void setab(int n); // функция setab()

int geta(){return a;} // функция geta()

};

void Samp::setab(int n){ // определение фукции setab()

a = n; b = n * n; // прямой доступ к a и b

// int b = 999; // локальная переменная b

// cout<<"b-localnaya "<
// cout<<"b-member class "<<Samp::b<
}

int main(){

Samp ob; // объект ob типа Samp

ob.setab(5); // установка a и b

cout<' '<a = 5 b = 25

ob.b = 55; // прямой доступ к b

cout<' '<a =5 b = 55

}

Переменные, определённые в функции класса, имеют область видимости функцию (они известны только этой функции). Если функция класса определяет переменную с тем же именем, что и у переменной, определённой в классе, последняя делается невидимой в функции. Такая скрытая переменная может быть доступна посредством операции разрешения области видимости (::), например, как в нашем примере Samp::b.

Локальные и глобальные объекты


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

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

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


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

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

// Пример 12.2. Присваивание объектов.

#include

using namespace std;

class myClass{ // определение класса myClass

int a, b;

public:

void set(int n, int m){a = n; b = m;}

void show(){cout<' ' <
};

class yourClass{ // определение класса yourClass

int a, b;

public:

void set(int n, int m){a = n; b = m;}

void show() {cout<' ' <
};

int main(){

myClass ob1, ob2; yourClass ob3;

ob1.set(5, 6); ob2 = ob1; // ошибки нет, объекты одного типа

// ob3 = ob1; // ошибка, объекты разных типов

system("pause");

}

Конструкторы и деструкторы


В языке С++ нельзя инициализировать объект тем же способом, что и встроенные типы, например, int или float, поэтомубыла создана специальная функция класса, называемая конструктором.

Конструкторэто специальная функция класса, которая вызывается автоматически при создании объекта и предназначена для его инициализации. Конструктор должен иметь то же имя, что и класс (чтобы компилятор смог её определить).

Конструкторы глобальных объектов вызываются до вызова функции main(). Для локальных объектов конструктор вызывается всякий раз при создании объекта. Если класс не содержитни одногоконструктора, он создаётся компилятором как функция без параметров и с пустым телом.

Основные правила использования конструктора:

  • конструктор не может возвращать значение, даже типа void;

  • конструктор должен быть открытым членом класса;

  • класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации;

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

Деструкторэто функция класса, которая вызывается автоматически при удалении объекта.

Основные правила использования деструктора:

  • имя деструктора начинается c символа тильды (), непосредственно за которым следует имя класса;

  • деструктор не может иметь параметров, не может возвращать значение;

  • нельзя перегружать деструктор;

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

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

// Пример 12.3. Использование конструктора и деструктора.

#include

using namespace std;

class Samp{ // определение класса Samp

int a;

public:

Samp(){a = 0;} // конструктор

void show(){cout<<"a = "<show()

Samp(){cout<<"Destructor"<
};

int main(){

Samp ob; // создание объекта ob, вызов конструктора

ob.show(); // a = 0

system("pause");

}

Конструкторы с параметрами


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

// Пример 12.4. Определение класса для работы с целыми числами.

// Нахождение суммы двух целых чисел.

// Использование конструктора с параметрами.

#include

using namespace std;

class Chisla{ // определение класса Chisla

int a, b; // число a, b

public:

Chisla(int x, int y){ a = x; b = y;} // конструктор с параметрами

int sum(){return a + b;} // функция суммы чисел

void show(); // функция вывода чисел

};

void Chisla::show(){

cout<<"a = "<>n>>m;

Chisla ob(n, m); // объект ob класса Chisla

ob.show(); int s = ob.sum(); // вызов функций show() и sum()

cout<<"summa = "<
system("pause");

}

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


Если в классе не определено ни одного конструктора, компилятор сгенерирует для класса конструктор по умолчанию вида:

Samp::Samp(){} // неявный конструктор по умолчанию

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

Samp::Samp(){a = n;} // явный вид конструктора по умолчанию

Этот конструктор не имеет параметров, но им можно воспользоваться для инициализации данных объекта определёнными значениями.

Конструктор с параметрами также может быть конструктором по умолчанию, но для этого все параметры конструктора должны быть заданы как аргументы по умолчанию, причём такие параметры можно задавать только в прототипе функции-конструктора внутри определения класса, и в программе не должно быть другого конструктора по умолчанию:

Samp::Samp(int n = 0, int b = 0){a = n; b = m;}

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

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

// Пример 12.5. Определение класса для вычисления объёма куба.

// Использование конструктора с аргументами по умолчанию.

#include

using namespace std;

class Cub{ // определение класса Cub

int len, wid, hei;

public:

Cub(int le = 1, int wi = 1, int he = 1); // конструктор по умолчанию

void show(){cout<' '<' '<
int volum(){return len * wid * hei;}

};

Cub::Cub(int le, int wi, int he){

len = le ; wid = wi; hei = he;

}

int main(){

Cub ob1, ob2(3), ob3(5, 4, 3);

ob1.show(); cout<<" v = "<
ob2.show(); cout<<" v = "<
ob3.show(); cout<<" v = "<
system("pause");

}

Перегрузка конструкторов


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

// Пример 12.6. Перегрузка конструктора для случая инициализации объекта

// явно указанными значениями и значениями, заданными по умолчанию.

#include

using namespace std;

class Samp{ // определение класса Samp

int x, y;

public:

Samp(){x = rand() % 20; y = rand() % 20;}

Samp(int m, int n){x = m; y = n;}

void show();

};

void Samp::show(){

cout<' '<
}

int main(){

int a, b;

cout<<"vvedi a, b :"; cin>>a>>b;

srand(a+b);

Samp ob1(a, b); // объект с явной инициализацией

Samp ob2; // объект без явной инициализации

ob1.show();

ob2.show();

system("pause");

}

Массивы объектов


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

// Пример 12.7. Создание и использование одномерного массива объектов.

#include >

using namespace std;

class Samp{

int x;

public:

void setx(int n){x = n;}

int getx(){return x;}

};

int main(){

Samp ob[4]; // массив объектов из 4-х элементов

for(int i = 0; i < 4; i++) // присваивание элементам массива

ob[i].setx(i); // значений от 0 до 3

for(int i = 0; i < 4; i++) // чтение элементов массива

cout<< ob[i].getx()<<' '; // и вывод их на экран – 0 1 2 3

system("pause");

}

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

Аналогично создаётся` и используется двумерный массив объектов:



Samp ob[2][4]; // двумерный массив объектов

// из 2 строк и 4 столбцов

int k = 1;
for(int i = 0; i < 2; i++) // присваивание элементам массива

for(int j = 0; j < 4; j++){ // объектов значений от 1 до 8

ob[i][j].setx(k); k++;

cout<< ob[i][j].getx()<<' '; // вывод элементов массива объектов

}



Если класс включает конструктор с параметрами, то массив объектов такого класса можно инициализировать явно.

// Пример 12.8. Явная инициализация одномерного массива объектов.

#include >

using namespace std;

class Samp{

int x;

public:

Samp(int n){x = n;}

int getx(){return x;}

};

int main(){

Samp ob[4] = { 1, 2, 3, 4 }; // создание массива объектов ob,

// вызов конструктора 4 раза

for(int i = 0; i < 4; i++) // вывод элементов массива ob

cout<< ob[i].getx()<<' '; // 1 2 3 4

system("pause");

}

написать администратору сайта