Программирование >>  Поддержка объектно-ориентированного программирования 

1 ... 5 6 7 [ 8 ] 9 10 11 ... 120


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

int pow ( int, int ); double pow ( double, double );

x = pow ( 2,10 ); вызов pow ( int, int ) y = pow ( 2.0, 10.0 ); вызов pow ( double, double )

Такое многократное использование имени называется перегрузкой имени функции или просто перегрузкой; перегрузка рассматривается особо в главе 7.

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

void swap ( int * p, int * q )

int t = * p;

* p = * q;

* q = t;

Унарная операция * называется косвенностью (или операцией разыменования), она выбирает значение объекта, на который настроен указатель. Функцию можно вызывать следующим образом:

void f ( int i, int j )

swap ( & i, & j );

Если использовать передачу параметра по ссглке, можно обойтись без явных операций с указателем: void swap (int & r1, int & r2 )

int t = r1;

r1 = r2; r2 = t;

void g ( int i, int j )

swap ( i, j );

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

1.3.6 Модули

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

extern C double sqrt ( double ); extern ostream cout;

Самый распространенный способ обеспечить согласованность описаний внешних во всех исходных



char * prog name = примитивный, но законченный пример ; int main ()

#include header.h c i

f();

а строка печатается функцией из файла f.c:

f.c

#include <stream.h> #include header.h

void f ()

cout << prog name << \n;

При запуске транслятора С++ и передаче ему необходимых файлов-параметров в различных реализациях могут использоваться разные расширения имен для программ на С++. На машине автора трансляция и запуск программы выглядит так:

$ CC main.c f.c -o silly $ silly

примитивный, но законченный пример

Кроме раздельной трансляции концепцию модульности в С++ поддерживают классы ($$5.4).

файлах - поместить такие описания в специальные файлы, называемые заголовочными. Заголовочные файлы можно включать во все исходные файлы, в которых требуются описания внешних. Например, описание функции sqrt хранится в заголовочном файле стандартных математических функций с именем math.h, поэтому, если нужно извлечь квадратный корень из 4, можно написать:

#include <math.h> x = sqrt ( 4 );

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

В команде включения заключенное в угловые скобки имя файла (в нашем примере - <math.h>) ссылается на файл, находящийся в стандартном каталоге включаемых файлов. Часто это - каталог /usr/include/CC. Файлы, находящиеся в других каталогах, обозначаются своими путевыми именами, взятыми в кавычки. Поэтому в следующих командах:

#include mathl.h #include /usr/bs/math2.h

включаются файл math1.h из текущего каталога пользователя и файл math2.h из каталога /usr/bs.

Приведем небольшой законченный пример, в котором строка определяется в одном файле, а печатается в другом. В файле header.h определяются нужные типы:

header.h

extern char * prog name; extern void f();

Файл main.c является основной программой:

main.c



Язык программирования С++

Поддержка абстракции данных

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

1.4.1 Инициализация и удаление

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

Например:

class vector

public:

void init ( init size );

вызов init () перед первым использованием объекта vector

void f ()

vector v; пока v нельзя v.init ( 10 ); теперь можно

использовать

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

class vector

int sz; int * v; public:

vector ( int );

~vector ();

int& operator [] ( int index ) ;

число элементов

указатель на целые

конструктор

деструктор

операция индексации

Конструктор класса vector можно использовать для контроля над ошибками и выделения памяти:

vector::vector ( int s )

if ( s <= 0 )

error ( недопустимый размер вектора ); sz = s;

v = new int [ s ]; разместить массив из s целых



1 ... 5 6 7 [ 8 ] 9 10 11 ... 120

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика