Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)


 

 

 

 



Инициализация и разрушение (конструкторы и деструкторы)



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

 

Для класса String имеет смысл в качестве начального значения использовать пустую строку:

class String

{

public:

String(); // объявление конструктора

};

// определение конструктора

String::String()

{

str = 0;

length = 0;

}

 

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

 

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

 

 

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

 

Если деструктор в определении класса не объявлен, то при уничтожении объекта никаких действий не производится.

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

 

 

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

Item::Item() : taken(false), invNumber(0)

{}

 

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

 

 

19. Инициализация массивов по умолчанию. Явная инициализация массивов.

Инициализация по умолчанию в С++

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

Эта программа на языке С демонстрирует инициализацию массивов,

выполняемую по умолчанию.

 

#include ‹stdio.h›

#define iGLOBAL_ARRAY_SIZE 10 #define iSTATIC_ARRAY_SIZE 20 int iglobal_array[iGLOBAL_ARRAY_SIZE];

/* глобальный массив */ main () { static int istatic_array[iSTATIC_ARRAY_SIZE];

/* статический массив */ int i;

for (i = 0; i < iGLOBAL_ARRAY_SIZE; i++) printf ("iglobal_array [%d].:%d\n",i, iglobal_array [i] ) ;

for(i= 0; i < iSTATIC_ARRAY_SIZE; i++) printf("istatic_array[%d]: %d\n", i, istatic_array[i]); return(0); }

 

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

 

Явная инициализация в С++

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

В следующем фрагменте программы содержится объявление четырех массивов, инициализируемых явно:

 

int iarray[3] = {-1,0, 1};

static float fpercent[4] = {1.141579,0.75,55E0,-.33E1);

static int ideoimal[3] = {0,1, 2, 3, 4, 5, 6, 7, 8, 9};

char cvowels[] = {'A','a','E','e','I','i','O','o','U','u'};

 

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

 

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

 

В третьей строке показан пример задания большего числа элементов массива, чем в нем на самом деле содержится. Многие компиляторы рассматривают подобную ситуацию как ошибку, тогда как другие автоматически увеличивают размер массива, чтобы вместить дополнительные элементы. Компилятор MicrosoftVisualC++ выдаст ошибку вида "too many initializers" (слишком много инициализаторов). В противоположной ситуации, когда при инициализации указано меньше значений, чем элементов массива, оставшиеся элементы по умолчанию примут нулевые значения.

 

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

20. Инициализация безразмерных массивов

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

 

Задать соответствующий массив символов можно двумя способами. Вот первый из них:

 

char sz!nput_Errdr[41] = "Введите значения от 0 до 9.\n";

char szDevice_Error[18] = "Диск недоступен.\n";

char szMonitor_Error[49] = "Для работы программы необходим цветной монитор. \n";

char szWarning[36]= "Эта операция приведет к удалению файла!\n";

 

Здесь необходимо предварительно подсчитать число символов в строке, не забыв к полученному числу прибавить 1 для символа \0,обозначающего конец строки. Это нудная работа, к тому же чреватая ошибками. Можно позволить компилятору автоматически вычислить размер массива, как показано ниже:

 

char szInput_Error[] = "Введите значения от 0 до 9.\n";

char szDevice_Error[] = "Диск недоступен.\n";

char szMonitor_Error[] = "Для работы программы необходим цветной монитор.\n";

char szWarning[] = "Эта операция приведет к удалению файла!\n";

 

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

 

21.Инкапсуляция, наследование и полиморфизм

Инкапсуляция

Инкапсуляция (encapsulation) - это механизм, который объединяет данные и код, манипулирующий зтими данными, а также защищает и то, и другое от внешнего вмешательства или неправильного использования. В объектно-ориентированном программировании код и данные могут быть объединены вместе; в этом случае говорят, что создаётся так называемый "чёрный ящик". Когда коды и данные объединяются таким способом, создаётся объект (object). Другими словами, объект - это то, что поддерживает инкапсуляцию.

Внутри объекта коды и данные могут быть закрытыми (private). Закрытые коды или данные доступны только для других частей этого объекта. Таким образом, закрытые коды и данные недоступны для тех частей программы, которые существуют вне объекта. Если коды и данные являются открытыми, то, несмотря на то, что они заданы внутри объекта, они доступны и для других частей программы. Характерной является ситуация, когда открытая часть объекта используется для того, чтобы обеспечить контролируемый интерфейс закрытых элементов объекта.

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

Полиморфизм

Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных. Например для языка Си, в котором полиморфизм поддерживается недостаточно, нахождение абсолютной величины числа требует трёх различных функций: abs(), labs() и fabs(). Эти функции подсчитывают и возвращают абсолютную величину целых, длинных целых и чисел с плавающей точкой соответственно. В С++ каждая из этих функций может быть названа abs(). Тип данных, который используется при вызове функции, определяет, какая конкретная версия функции действительно выполняется. В С++ можно использовать одно имя функции для множества различных действий. Это называется перегрузкой функций (function overloading).

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

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

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

Наследовние

Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование является важным, поскольку оно позволяет поддерживать концепцию иерархии классов (hierarchical classification). Применение иерархии классов делает управляемыми большие потоки информации. Например, подумайте об описании жилого дома. Дом - это часть общего класса, называемого строением. С другой стороны, строение - это часть более общего класса - конструкции, который является частью ещё более общего класса объектов, который можно назвать созданием рук человека. В каждом случае порождённый класс наследует все, связанные с родителем, качества и добавляет к ним свои собственные определяющие характеристики. Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы исчерпывающи его определяли. Однако при использовании наследования можно описать объект путём определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным. Наследование играет очень важную роль в OOP.

 

 



Просмотров 1616

Эта страница нарушает авторские права




allrefrs.su - 2024 год. Все права принадлежат их авторам!