Мегаобучалка Главная | О нас | Обратная связь


Как можно эмулировать прямой доступ к строкам в текстовом файле?



2019-08-13 187 Обсуждений (0)
Как можно эмулировать прямой доступ к строкам в текстовом файле? 0.00 из 5.00 0 оценок




Символы F, N, h, l и L являются символами размера, переопределяющими размер по умолчанию. Символы F и N применяются с указателями, far и near соответственно. Символы h, l , и L используются для указания соответственно типов short int, long или long double.

Символам типа данных должен предшествовать форматирующий символ %. В таблице 7.2 мы показали возможные значения флагов форматирующей строки printf. Символы типов данных перечислены в таблице 7.3.

Таблица 3. Символы типов данных строки формата функции printf

Тип данных символ типа результат
Символ c Один символ
  d Десятичное целое со знаком
  i Десятичное целое со знаком
  O Восьмеричное целое без знака
  N Десятичное целое без знака
  X Шестнадцатеричное целое без знака; набор цифр - 0123456789abcdef
  X Шестнадцатеричное целое без знака; набор цифр - 0123456789ABCDEF
Указатель P Для указателей near выводит только смещение в виде: 0000. Указатели far отображаются в виде: SSSS:0000
Указатель на целое N  
Вещественное F Выводит величину со знаком в формате [-]dddd.dddd
  E Выводит вещественную величину со знаком в экспоненциальном формате [-]d.dddde[+|-]ddd
  Е Выводит вещественную величину со знаком в экспоненциальном формате [-]d.ddddE[+|-]ddd
  G Выводит вещественную величину со знаком в формате f или е в зависимости от ее значения и заданной точности
  G Выводит вещественную величину со знаком в формате F или Е в зависимости от ее значения и заданной точности
Указатель S Выводит строку символов, пока не встретит нуль-терминатор строки

 

Разберем небольшой пример. Программа OUT2.CPP, исходный код которой приведен в листинге 3, создана на основе программы OUT1.CPP. В этой программе используется форматированный вывод с использованием функции printf. Программа выводит те же числа, что и OUT1.CPP, используя три различных набора спецификаций преобразования.

Листинг 3. Исходный текст программы OUT2.CPP в файле List7-3.CPP

 

01 // Программа, использующая printf для форматирования вывода
02  
03 #include <stdio.h>
04  
05 int main()
06 {
07  int anInt = 67;
08  Unsigned char aByte = 128;
09  char aChar = '@';
10  Float aSingle = 355.0;
11  Double aDouble = 1.130e+002;
12  
13  Printf("%3d + %2d = %3d\n",
14  aByte, anInt, aByte + anInt );
15  
16  Printf("Вывод использует спецификации преобразования %%lf :\n");
17  Printf(" %6.4f / %10.4lf = %7.5lf\n",
18  aSingle, aDouble, aSingle / aDouble );
19  
20  Printf("Вывод использует спецификации преобразования %%le :\n");
21  printf(" %6.4e / %6.4le = %7.5le\n",
22  aSingle, aDouble, aSingle / aDouble );
23  
24  printf("Вывод использует спецификации преобразования %%lg :\n");
25  printf(" %6.4g / %6.4lg = %7.5lg\n",
26  aSingle, aDouble, aSingle / aDouble );
27  
28  printf("Символьная переменная aChar: %c\n", aChar);
29  printf("ASCII-код %c: %d\n", aChar, aChar);
30  return 0;
31 }

Пример вывода программы из листинга 3:

128 + 67 = 195

Вывод использует спецификации преобразования %lf :

 355.0000 / 113.0000 = 3.14159

Вывод использует спецификации преобразования %le :

 3.5500e+02 / 1.1300e+02 = 3.14159e+00

Вывод использует спецификации преобразования %lg :

 355 / 113 = 3.1416

Символьная переменная aChar: @

ASCII-код @: 64

В программе из листинга 3 объявляется целый набор переменных различных типов. Оператор вывода в строках 13 и 14 выводит целые, используя спецификацию формата %d. В таблице 4 приведены результаты действия спецификаций преобразования из строки 13. Обратите внимание на то, что первая переменная была преобразована из типа unsigned char в тип integer.

Таблица 4. Результат действия спецификаций форматирования в функции printf из строки 13

Спецификация формата Переменная Тип данных Тип после преобразования
%3d aByte unsigned char Int
%2d anInt int Int
%3d aByte + anInt int Int

 

Оператор вывода в строке 17 выводит переменные aSingle, aDouble и выражение aSingle / aDouble, используя спецификации преобразования %6.4f, %6.41f и % 7.51f. Точность представления задается ими равной 4, 4 и 5 цифрам, а минимальная ширина поля 6, 6 и 7 цифрам соответственно. Две последних спецификации осуществляют преобразование величин двойной точности.

Оператор вывода в строке 21 подобен оператору из строки 17. Отличие состоит в том, что используется е-формат вместо f-формата. Соответственно три значения выводятся в экспоненциальном формате.

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

Оператор вывода в строке 28 выводит содержимое переменной aChar по формату %с. Оператор вывода в строке 29 выводит ту же переменную aChar дважды, первый раз как символ, а второй раз как целое (или, если быть точным, выводится ASCII-код символа). Для этого используются спецификации преобразования %с и %d соответственно.

Массивы символов в C++

В C++ имеется специальный класс для работы со строками, которого, конечно, не было в языке С. В С строки вводились как массивы символов, ограниченные нуль-символом (ASCII-код которого равен нулю), поэтому большое количество программ, написанных на С, используют символьные массивы. Более того, и в C++, несмотря на то, что он имеет класс для работы со строками, находится применение массивам символов. Поэтому термин “строка” имеет два значения: строка в смысле C++ и строка как массив символов. Весь этот раздел будет посвящен тому, как нужно и не нужно использовать символьные массивы.

Символ '\0' также называют нуль-терминатором. Строки, оканчивающиеся нуль-терминатором, называют еще ASCIIZ-строками, где символ Z обозначает ноль — ASCII-код нуль-терминатора. Еще этот символ называют NUL-символом, поскольку этот термин является его именем в ASCII.

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

Ввод строк

В программах, которые мы рассматривали, операторы потокового вывода выводили строковые константы; C++ поддерживает потоковый вывод для строк как специального не-предопределенного типа данных. (Можно сказать, что это было сделано по требованию масс.) Операции и синтаксис для вывода строковых переменных остаются прежними. При вводе строк операция извлечения из потока ” не всегда будет работать так, как вы ожидаете, поскольку строки часто содержат пробелы, которые игнорируются оператором ввода; поэтому вместо оператора ввода вам нужно использовать функцию getline. Эта функция вводит заданное количество символов.

Функция getline

Перегруженная функция getline объявляется следующим образом:

istreams getline( signed char *buffer,

int size,

char delimiter = '\n') ;

istreams getline( unsigned char *buffer,

int size,

char delimiter = '\n') ;

istream& getline( char *buffer,

int size,

char delimiter = '\n') ;

Параметр buffer является указателем на строку, в которую помещаются вводимые символы. Параметр size задает максимальное количество вводимых символов. Параметр delimeter определяет символ-ограничитель, при появлении которого ввод символов прекращается прежде, чем будут введены все size символов. Параметр delimeter имеет аргумент по умолчанию, равный '\n'. В случае ввода символов с клавиатуры этот символ появляется в потоке ввода при нажатии клавиши

Пример

#include <iostream.h> //см. файл Ex01.cpp

int main()

{

char name[80] ;

cout “ "Enter your name: ";

cin.getline(name, sizeof(name) - 1);

cout “ "Hello " “ name “ ", how are you?";

return 0;

}

Функции, объявленные в STRING. H

Стандартная библиотека для работы со строками содержит много полезных функций (объявляемых в STRING.H), разработанных коллективными усилиями многих программистов на С. В файлах заголовка STDIO.H и IOS-TREAM.H также имеются прототипы строковых функций. Комитетом ANSI/ISO C++ предложен класс для работы со строками. Строки этого класса больше похожи на строки в языках Pascal и BASIC. (Мы познакомимся с классами в День 8, а со строковым классом в День 11.) Этот раздел будет посвящен рассмотрению некоторых (ни в коей мере не всех) функций, объявленных в STRING.H.

Некоторые функции из STRING.H имеют несколько версий. Дополнительные версии этих функций, имеющих в имени префиксы _f, f или _ работают с указателями типа far. Этих версий вы не встретите в плоской, 32-битной модели памяти компилятора Borland.

Присвоение значений строкам

C++ поддерживает два способа присвоения значений строкам. Вы можете присвоить строковой переменной строковую константу, произведя инициализацию при объявлении строки. Этот метод прост: требуется операция присваивания и строковая константа.

Инициализация строки

Общий метод инициализации строки:

char stringVar[stringSize] = stringLiteral;

Пример

char a3tring[81] = "Borland C++ 5 in 21 days";

char Named = "Rene Kinner";

 

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

Функция strcpy

Прототип функции strcpy таков:

char* strcpy(char *target, const char *source);

Функция копирует строку source в строку target. Функция предполагает, что целевая строка имеет размер, достаточный для того, чтобы вместить содержимое строки-источника.

Пример

char name[41] ;

strcpy(name, "Borland C++ 5");

 

Переменная name содержит строку "Borland C++ 5".

Функция strdup

Функция strdup копирует одну строку в другую, при этом отводит необходимое количество памяти для целевой строки.

Прототип функции strdup таков:

char* strdup(const char *source);

Функция копирует строку source и возвращает указатель на строку-копию.

Пример

char *string1 = "Монархия в Испании";

char *string2;

string2 = strdup(string1);

 

После того, как будет отведено необходимое количество памяти для строки string2, строка string1будет скопирована в строку string2.

Функция strncpy

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

Прототип функции strncpy таков:

char * strncpy(char *target, const char *source, size_t num);

Функция копирует num символов из строки source в строку target. Функция не выполняет ни усечение, ни заполнение строки.

Пример

char str1[] = "Pascal";

char str2[] = "Hello there";

strcnpy(strl, str2, 5);

 

Переменная strl содержит строку "Hellol". Заметьте, что символ ‘l’ строки-приемника, следующий за скопированной частью строки, сохранился.

Определение длины строки

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

Функция strlen

Функция strlen возвращает количество символов в строке, в которое не включается нуль-терминатор.

Прототип функции strncpy таков:

size_t strlen (const char *st ri ng) ,

Функция strlen возвращает длину строки string. size_t — это имя, приписанное типу unsigned int оператором typedef.

Пример

char str[] = "1234567890";

size_t i;

i = strlen(str),

 

Переменной i будет присвоено значение 10.

Конкатенация строк

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

Присоединить одну строку к другой можно функцией strcat.

Функция strcat

Конкатенация строк означает их последовательное присоединение друг к другу.

Прототип функции strcat таков:

char *strcat(char *target, const char *source) ;

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

Пример

char string[81] ;

strcpy(string, "Turbo");

strcat (string, " C++");

 

Переменная string содержит строку "Turbo C++".

Функция strncat

Функция strncat добавляет к содержимому целевой строки указанное количество символов из строки-источника.

Прототип функции strcat :

char *strncat(char *target, const char *source, size_t num) ;

Функция добавляет к содержимому целевой строки num символов из строки-источника и возвращает указатель на целевую строку.

char strl[81] = "Hello I am ";

char str2[41] = "Keith Thompson";

strncat(strl, str2, 5);

 

Переменная strl теперь содержит строку "Hello I am Keith".

Пример использования функций getline, strlen и strcat в файле List7_4.cpp (исходный код программы STRING.CPP). Программа выполняет следующие задачи:

· Предлагает вам ввести строку; ввод не должен превышать 40 символов

· Предлагает вам ввести вторую строку; ввод не должен превышать 40 символов

· Выводит число символов, содержащихся в каждой строке

· Присоединяет вторую строку к первой

· Выводит результат конкатенации

· Выводит длину объединенной строки

· Предлагает вам ввести символ для поиска

· Предлагает вам ввести символ для замены

· Выводит содержимое объединенной строки после замены символа

Сравнение строк

Поскольку строки являются массивами символов, вы не можете применить операцию сравнения для проверки равенства двух строк. Библиотека функций STRING.H предлагает набор функций для сравнения строк. Эти функции сравнивают символы двух строк, используя для этого ASCII-коды символов. Это функции strcmp, stricmp, strncmp и strnicmp.

Вообще говоря, все функции сравнения работают одинаково: возвращают 0, если две строки совпали, отрицательную величину, если вторая строка больше по величине, и положительное значение, если большей оказалась первая строка.

Функция strcmp

Функция strcmp выполняет сравнение двух строк с учетом регистра символов.

Прототип функции strcmp:

int strcmp(const char *strl, const char *str2);

Функция сравнивает строки strl и str2. Возвращает в качестве результата сравнения целую величину:

< 0 когда strl меньше, чем str2;

= 0 когда strl равна str2;

> 0 когда strl больше, чем str2.

Пример

char stringl[] = "Borland C++";

char string2[] = "BORLAND C++";

i = strcmp(string1, string2);

 

В последнем операторе переменной i присваивается положительное значение, так как string1 больше string2 (ASCII-коды символов в нижнем регистре больше ASCII-кодов символов в верхнем.)

Функция stricmp

Функция stricmp выполняет сравнение двух строк, не учитывая регистра символов.

Прототип функции stricmp:

int stricmp(const char *strl, const char *str2);

Функция сравнивает строки strl и str2, не делая различия между символами в нижнем и верхнем регистре. Возвращает в качестве результата сравнения целую величину:

< 0 когда strl меньше, чем str24

= 0 когда strl равна str24

> 0 когда strl больше, чем str2.

Пример

char string1[] = "Borland C++";

char string2[] = "BORLAND C++";

int i = strcmp(string1, string2);

 

В последнем операторе переменной i присваивается значение 0, так как string1 и string2 отличаются друг от друга только регистром символов.

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

Функция strncmp

Прототип функции strncmp:

int strncmp(const char *strl, const char *str2, size_t num);

Функция сравнивает первые num символов строк strl и str2. Возвращает в качестве результата сравнения целую величину:

< 0 когда strl меньше, чем str2;

= 0 когда strl равна str2;

> 0 когда strl больше, чем str2.

Пример

char string1[] = "Borland C++";

char string2[] = "Borland Pascal";

i = stricmp(string1, string2, 9);

 

В последнем операторе переменной i присваивается отрицательное значение, так как значение "Borland С" меньше, чем "Borland Р".

Функция strnicmp

Функция strnicmp выполняет сравнение заданного количества символов двух строк без учета регистра символов.

Прототип функции strnicmp :

int strnicmp(const char *strl, const char *str2, size_t num);

Функция сравнивает первые num символов строк strl и str2, не делая различия в регистре символов. Возвращает в качестве результата сравнения целую величину:

< 0 когда strl меньше, чем str2;

= 0 когда strl равна str2;

> 0 когда strl больше, чем str2.

Пример

char string1[] = "Borland C++";

char string2[] = "BORLAND Pascal";

i = strnicmp(string1, string2, 7);

 

В последнем операторе переменной i присваивается значение 0, так как подстрока "Borland" отличается в этих строках только регистром.

Рассмотрим пример программы, в которой применяются функции сравнения строк. Программа из листинга 5 объявляет массив строк и присваивает им значения. Затем программа выводит исходный массив, сортирует его и выводит значения строк отсортированного массива. |

(см. List7_5.cpp - Исходный текст программы STRING2.CPP)

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

Функция strlwr

Прототип функции strlwr:

char* strlwr (char *source)

Функция преобразует символы верхнего регистра в символы нижнего регистра в строке source. Другие символы не затрагиваются. Функция возвращает указатель на строку source.

Пример

char str[] = "HELLO THERE";

strlwr(str);

 

Переменная str теперь содержит строку "hello there".

Функция strupr

Прототип функции strupr:

char* strupr(char *source)

Функция преобразует символы нижнего регистра в символы верхнего регистра в строке source. Другие символы не затрагиваются. Функция возвращает указатель на строку source.

Пример

char str[] = "Borland C++";

strupr(str);

 

Переменная str теперь содержит строку "BORLAND С ++".

Обращение строк

Библиотека STRING.H предлагает функцию strrev для записи символов в строке в обратном порядке.

Функция strrev

Прототип функции strrev:

char* strrev(char *str)

Функция обращает порядок символов в строке str и возвращает указатель на строку str. char str[] = "Hello";

strrev(str) ;

cout “ str;

 

Будет выведено "olleH".

Рассмотрим программу, которая манипулирует символами в строке. List7_6.cpp показывает исходный текст программы STRING3.CPP. Программа выполняет следующие задачи:

· Запрашивает у вас ввод строки

· Отображает ваш ввод

· Выводит вашу строку в нижнем регистре

· Выводит вашу строку в верхнем регистре

· Отображает символы, которые вы ввели, в обратном порядке

· Выводит сообщение, что ваш ввод не содержит символов верхнего регистра, если это так

· Выводит сообщение, что ваш ввод не содержит символов в нижнем регистре, если это так

· Выводит сообщение, что ваша строка симметрична, если это так

· Поиск символов

Библиотека STRING.H предлагает ряд функций для поиска символов в строках. Это функции strchr, strrchr, strspn, strcspn и strpbrk. Они осуществляют поиск в строках символов и простых символьных шаблонов.

 

Функция strchr

Функция strchr определяет первое вхождение символа в строку.

Прототип функции strchr:

char* strchr(const char *target, int c)

Функция находит первое вхождение символа с в строку target. Функция возвращает указатель на символ в строке target, который соответствует заданному образцу с. Если символ с в строке не обнаруживается, функция возвращает 0.

Пример

char str[81] = "Borland C++";

char *strPtr;

strPtr = strchr(str, '+');

 

Указатель strPtr теперь содержит адрес подстроки "++" в строке str.

Функция strrchr

Функция strrchr определяет последнее вхождение символа в строке.

Прототип функции strrchr:

char* strrchr(const char *target, int c)

Функция находит последнее вхождение символа с в строку target. Функция возвращает указатель на символ в строке target, который соответствует заданному образцу с. Если символ с в строке не обнаруживается, функция возвращает 0.

Пример

char str[81] = "Borland C++ is here";

char* strPtr;

strPtr = strrchr(str, '+');

 

Указатель strPtr теперь указывает на подстроку "+ is here " в строке str.

Функция Strspn

Функция strspn возвращает число символов с начала строки, совпадающих с любым символом из шаблона.

Прототип для функции strspn:

size_t strspn(const char *target, const char *pattern)

Функция strspn возвращает число символов от начала строки target, совпадающих с любым символом из шаблона pattern.

Пример

char str[] = "Borland C++ 5";

char substr[] = "narlBod";

int index;

index = strspn(str, substr);

 

Этот оператор присваивает 8 переменной index, потому что первые восемь символов из str содержатся в подстроке substr.

Функция strcspn

Функция strcspn просматривает строку и выдает число первых символов в строке, которые не содержатся в шаблоне.

Прототип функции strcspn:

size_t strcspn(const char* str1, const char* str2)

Функция strcspn просматривает строку str1 и выдает длину подстроки, отсчитываемой с начала строки, символы которой полностью отсутствуют в строке str2.

Пример

char strng[] = "The rain in Spain";

int i = strcspn(strng, " in");

 

Этот пример возвращает 3 (расположение первого пробела в строке strng) переменной i.

 

Функция strpbrk

Функция strpbrk просматривает строку и определяет первое вхождение любого символа из образца.

Прототип функции strpbrk:

char* strpbrk(const char* target, const char* pattern)

Функция strpbrk ищет в строке target первое вхождение любого символа из образца pattern. Если символы из образца не содержатся в строке, функция возвращает 0.

Пример

char *str = "Hello there how are you";

char *substr = "hr";

char *ptr;

ptr = strpbrk(str, substr);

cout “ ptr “ endl;

 

Вы увидите на экране строку "here how are you", потому что 'h' встречается в строке str раньше, чем 'r'.

Поиск строк

Библиотека функций STRING.H предлагает для поиска подстроки в строке функцию strstr.

Функция strstr

Прототип функции strstr:

char* strstr(const char *str, const char *substr) ;

Функция ищет в строке str первое вхождение подстроки substr. Функция возвращает указатель на первый символ найденной в строке str подстроки substr. Если строка substr не обнаружена в строке str, функция возвращает 0.

Пример

char str[] = "Hello there! how are you";

char substr[] = "how";

char *ptr;

ptr = strstr (str, substr);

cout “ ptr “ endl ;

 

Это приведет к выводу строки "how are you", поскольку в строке str , была обнаружена подстрока "how". Указатель ptr содержит адрес остатка первоначальной строки, начинающегося с подстроки "how".

Функция strtok

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

Подстроки иногда называются лексемами.

Прототип функции strtok:

char* strtok(char *target, const char * delimiters );

Функция разбивает строку на лексемы, согласно символам-ограничителям, заданным в параметре delimeters. В следующем примере показано, как работать с этой функцией и как получать лексемы, на которые была разбита строка. Функция strtok вводит символ '\0' после каждой лексемы. (Опять же не забудьте сохранить копию вашей строки в другой строковой переменной.)

Пример

#include <stdio.h> // см. файл Ex02.cpp

#include <string.h>

int main()

{

char *str = "(Base_Cost + Profit) * Margin";

char *tkn = "+*()";

char *ptr = str;

printf("%s\n", str);

// Первый вызов функции

ptr = strtok(str, tkn);

printf("Лексемы этой строки: %s", ptr);

while (ptr)

{

// Первый аргумент должен быть равен нулю

if ((ptr = strtok(0, tkn)) != 0)

printf (",%s", ptr);

}

printf("\n");

return 0;

}

 

В результате выполнения этой программы на экран выводятся следующие строки:

(Base_Cost + Profit) * Margin

Лексемы этой строки: Base_Cost, Profit, Margin

 

Рассмотрим пример программы поиска символов и строк. Листинг 7 (List7_7.cpp) содержит исходный текст программы STRING4.CPP. Программа выполняет следующие задачи:

· Запрашивает у вас ввод основной строки

· Запрашивает строку поиска

· Предлагает вам ввести символ поиска

· Выводит линейку цифр и основную строку

· Выводит номер символа в основной строке, с которого начинается строка поиска *

· Выводит номер символа в основной строке, совпавшего с символом поиска.

 

Основы объектно-ориентированного программирования СИНТАКСИС ОСНОВНЫХ КОНСТРУКЦИЙ

Объявление базовых классов

 

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

 

 Базовый класс

 

 Базовый класс определяется следующим образом (синтаксис):

 

class className

{

private:

 <закрытые элементы-данные>

 <закрытые конструкторы>

 <закрытые функции-элементы>

protected:

 <защищенные элементы-данные>

 <защищенные конструкторы>

 <защищенные функции-элементы>

public:

 <открытые элементы-данные>

 <открытые конструкторы>

 <открытый деструктор>

 <открытые функции-элементы>

};

 

 Пример 1:

 

class point

{

protected:

 double х;

 double у;

public:

 point(double xVal, double yVal);

 double getX();

 double getY();

 void assign(double xVal, double yVal);

 point& assign(point &pt);

};

 

Разделы класса

 

 Классы С++ имеют три различных уровня доступа к своим элементам - как к данным, так и к функциям:

 

Закрытые (частные) элементы

Защищенные элементы

Открытые элементы

 

К данным в закрытом разделе имеют доступ только функции-элементы класса.

Классам-потомкам запрещен доступ к закрытым данным своих 6азовых классов.

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

 

Существуют следующие правила для разделов класса:

 

Разделы могут появляться в любом порядке.

Один и тот же раздел можно определять несколько раз.

Если не определен ни один раздел, компилятор (по умолчанию) объявляет все элементы закрытыми.

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

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

Класс может иметь несколько конструкторов.

Класс может иметь только один деструктор, который должен объявляться в открытом разделе класса.

Функции-элементы (в том числе конструкторы и деструкторы), состоящие из нескольких операторов, должны определяться вне объявления класса. Определение функции может содержаться в том же файле, в котором определяется класс. Это напоминает порядок работы с обычными функциями: задание прототипа и определение функции.

 

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

 

 При определении функции-элемента вы должны указать ее имя и имя ее класса. Сначала вы должны Сначала необходимо указать имя класса (т.н. квалификатор), а затем, через два двоеточия (::), имя функции. В качестве примера рассмотрим такой класс:

 

class point

{

protected:

 double x;

 double y;

public:

 point(double xVal, double yVal);

 double getX();

 // другие функции-элементы

};

 

Определения конструктора и функций-элементов должны выглядеть так

 

point::point (double xVal, double yVal)

{

 // операторы

}

double point::getX()

{

 // операторы

}

 

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

 В листинге 8.1 приведен исходный текст программы RECT.CPP. Программа предлагает вам ввести длину и ширину прямоугольника (в данном примере прямоугольник является объектом). Затем программа выводит значения длины, ширины и площади определенного вами прямоугольника.

 

Конструкторы

 

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

 

 Общий вид (синтаксис) объявления конструктора:

 

class className

{

public:

 className(); // конструктор по умолчанию

 className(const className &c); // конструктор копии

 className(<список параметров>); // остальные конструкторы

};

 

 Пример 2:

 

// Замечание: Здесь только объявление класса без описания объявленных

// функций-параметров

 

class point

{

protected:

 double x;

 double y;

public:

 point();

 point(double xVal, double yVal);

 point(const point &pt);

 double getX();

 double getY();

 void assign(double xVal, double yVal);

 point& assign(point &pt);

};

int main()

{

 point p1;

 point p2(10, 20);

 point p3(p2);

 p1.assign(p2);

 cout << p1.getX() << " " << p1.getY() << endl;

 cout << p2.getX() << " " << p2.getY() << endl;

 cout << p3.getX() << " " << p3.getY() << endl;

 return 0;

}

 

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

 

 В С++ имеются следующие особенности и правила работы с конструкторами:

 

Имя конструктора класса должно совпадать с именем класса.

 

Нельзя определять тип возвращаемого значения для конструктора, даже тип void.

 

Класс может иметь несколько конструкторов или не иметь их совсем.

 

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

 

 Рассмотрим два примера с фрагментами объявления конструкторов.

 

// класс с конструктором без параметров

class point1

{

protected:

 double x;

 double y;

public:

 point1();

 // другие функции-элементы

};

 

// конструктор класса имеет параметры со значениями по умолчанию

class point2

{

protected:

 double x;

 double y;

public:

 point2(double xVal = 0, double yVal = 0);

 // другие функции-элементы

};

 

Конструктор копии создает объект класса на основе существующего объекта.

Например:

 

class point

{

protected:

 double x;

 double y;

public:

 point();

 point(double xVal = 0, double yVal = 0);

 point(const point &pt);

 // другие функции-элементы

};

 

Объявление объекта класса, которое может содержать параметры и, в качестве параметра, имя уже существующего объекта, влечет за собой вызов конструктора. Но какой из конструкторов будет использоваться в каждом конкретном случае? Ответ зависит от того, как много конструкторов вы объявили и с какими аргументами вы объявляете объект класса. Например, рассмотрим следующие объявления объектов последней версии класса point:

 

point p1; // применяется конструктор по умолчанию

point p2(1.1, 1.3); // используется второй по счету конструктор

point p3(p2); // используется конструктор копии

 

 Поскольку объект p1 объявляется без параметров, компилятор использует конструктор по умолчанию. Объект p2 объявляется с двумя вещественными аргументами, поэтому компилятор вызовет второй конструктор. Объект p3 при объявлении имеет параметром объект p2, поэтому компилятор вызовет конструктор копии, чтобы создать новый объект из объекта p2.

 

 ВНИМАНИЕ:

 

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

 Не полагайтесь на поверхностный конструктор копии для классов имеющих данные-указатели.

 

Деструкторы

 

 Классы С++ могут содержать деструкторы, которые автоматически разрушают объекты класса.

 

 Общий синтаксис объявления деструктора:

 

class className

{

public:

 className(); // конструктор по умолчанию

 // другие конструкторы

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

 // другие функции-элементы

};

 

 Пример 3 на синтаксис обявления деструктора:

 

class String

{

protected:

 char *str;

 int len;

public:

 String();

 String(const String& s);

 ~String();

 // другие функции-элементы

};

 

 Деструкторы в С++ имеют следующие особенности и подчиняются следующим правилам:

 

Имя деструктора должно начинаться со знака тильды (~), за которым должно следовать имя класса.

 

Нельзя определять тип возвращаемого значения, даже тип void.

 

Класс может иметь только один деструктор или ни одного. В последнем случае компилятор создаст деструктор по умолчанию.

 

Деструктор не должен иметь параметров.

 

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

 

(см. LIST8-2.CPP)

 

Объявление иерархии классов

Производный класс

 

 Общая форма (синтаксис) объявления производного класса:

 

class classname : [<спецификатор доступа>] parentClass

{

<дружественные классы>

private:

 <закрытые элементы-данные>

 <закрытые конструкторы>

 <закрытые функции-элементы>

protected:

 <защищенные элементы-данные>

 <защищенные конструкторы>

 <защищенные функции-элементы>

public:

 <открытые элементы-данные>

 <открытые конструкторы>

 <открытый деструктор>

 <открытые функции-элементы>

<дружественные функции и дружественные операции>

};

 

 Пример 4 объявления класса Rectangle и класса-потомка Box:

 

class Rectangle

{

protected:

 double length;

 double width;

public:

 Rectangle(double len, double wide);

 double getLength() const;

 double getWidth() const;

 double assign(double len, double wide);

 double calcArea();

};

class Вох : public Rectangle

{

protected:

 double height;

public:

 Box(double len, double wide, double height);

 double getHeight () const;

 assign(double len, double wide, double height);

 double calcVolume();



2019-08-13 187 Обсуждений (0)
Как можно эмулировать прямой доступ к строкам в текстовом файле? 0.00 из 5.00 0 оценок









Обсуждение в статье: Как можно эмулировать прямой доступ к строкам в текстовом файле?

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

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



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (187)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.014 сек.)