Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lr1.2012.docx
Скачиваний:
3
Добавлен:
24.11.2019
Размер:
13.72 Кб
Скачать
  1. Теоретическая часть

Для начала рассмотрим пример синтаксиса задания класса. Сам синтаксис класса схож с синтаксисом структуры.

class ИмяКласса : ИмяРодителя {

public:

// в этой секции задаются открытые члены класса

ИмяКласса(); // конструктор класса

~ИмяКласса(); // деструктор класса

protected:

// в этой секции задаются защищённые члены класса

private:

// в этой секции задаются закрытые члены класса

};

Задание класса начинается с ключевого слова class. За ним мы указываем имя объявляемого класса и базовые классы, если требуются. Далее, описываются элементы класса. Для управления инкапсуляцией используются ключевые слова public, protected и private. Эти ключевые слова разбивают класс на секции. Идти они могут в любой последовательности. На количество секций также ограничений не распространяется.

Для хранения данных внутри класса используются переменные, для действий класса – функции. Их принято называть полями и методами соответственно.

Также у класса есть два специфических метода: конструктор и деструктор.

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

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

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

    1. Начало создания класса

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

class MyString {

public:

char *ptr;

int length() {

return strlen(ptr);

}

void cat(MyString v){

strcat(ptr, v.ptr);

}

bool compare(MyString v){

return !strcmp(ptr, v.ptr);

}

};

Посмотрим на использование этого варианта.

MyString s1, s2;

cin>> s1.ptr >> s2.ptr;

if(s1.compare(s2))

cout << "Строки равны" << endl;

else

cout << "Строки неравны" << endl;

s1.concatenate(s2);

cout << s1.ptr << endl;

cout << s1.length() << endl;

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

MyString() {

ptr = new char[1];

}

MyString(char* s){

ptr = new char[1];

strcpy(ptr, s);

}

MyString(MyString s) {

ptr = new char[1];

strcpy(ptr, s.ptr);

}

Теперь мы можем использовать класс строки так:

MyString s1, s2("test"), s3(s2);

cin>> s1.ptr >> s2.ptr;

if(s1.compare(s2))

cout << "Строки равны" << endl;

else

cout << "Строки неравны" << endl;

s1.concatenate(s2);

cout << s1.ptr << endl;

cout << s1.length() << endl;

cout << s2.ptr << endl;

cout << s3.ptr << endl;

Замечу, что предыдущий вариант использования был не работоспособен поскольку требуется инициализировать указатель на строку. Что не было сделано в первом варианте класса.

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

Как можно повысить эффективность класса? Для начала переместим данные в закрытую область. Но в этом случае, мы лишаемся возможности свободного доступа к данным, и, как следствие, вводу и выводу строки. Значит нужно добавить методы для ввода и вывода строки. В результате, класс будет выглядеть следующим образом:

class MyString {

char *ptr;

public:

MyString() {

ptr = new char[1];

}

MyString(char* s){

ptr = new char[1];

strcpy(ptr, s);

}

MyString(MyString s) {

ptr = new char[1];

strcpy(ptr, s.ptr);

}

int length() {

return strlen(ptr);

}

void concatenate(MyString v){

strcat(ptr, v.ptr);

}

bool compare(MyString v){

return !strcmp(ptr, v.ptr);

}

void input(){

cin >> ptr;

}

void output() {

cout << ptr;

}

};

Претерпят изменения и способ его использования.

MyString s1, s2("test"), s3(s2);

s1.input();

s2.input();

if(s1.compare(s2))

cout << "Строки равны" << endl;

else

cout << "Строки неравны" << endl;

s1.concatenate(s2);

cout << s1.length() << endl;

s1.output();

s2.output();

s3.output();

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]