Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_OOP.doc
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
4 Mб
Скачать

5. Неявный указатель this

Каждый объект класса имеет свою копию член-данных и один экземпляр каждой член-функции для всех объектов. Возникает вопрос, как же член-функция “понимает”, с член-данными какого объекта она работает? Ответ очевиден – с теми, которые принадлежат объекту, вызвавшему эту функцию.

Например,

s2.Print();

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

Например,

void Print() {cout << this –> line;}

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

Например, в классе String определим функцию, которая будет к первой строке приписывать вторую и результатом возвращать первую (конкатенация строк), объявив ее в классе

String Plus(String &);

и определив ее за классом:

String String :: Plus(String &s2)

{char *t = new char[len + 1];

strcpy(t, s.line); delete [ ]line;

len += s2.len; line = new char[len + 1];

strcpy(line, t); strcat(line, s2.line);

delete [ ] t;

return *this; // возвращаем “этот” объект

}

Пример использования этой функуции:

String s1(“Объект “), s2(“класса String.”);

String * s3 = new String(s1.Plus(s2));// работает функция Plus( ), а затем конструктор копирования

s3 –> Print(); // вывод *s3 = ”Объект класса String.”;

6. Перегрузка операций

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

Формат перегрузки двуместной операции имеет вид

тип_возвращаемого_значения operator @ (операнд_2)

{тело_операции},

где @ – знак операции.

Первым операндом является объект, с которым эта операция вызывается, то есть * this, второй операнд – произвольный.

Используется перегруженный знак так же, как для стандартных типов данных

операнд1 @ операнд2

В классе String вместо функции Plus( ) можно определить операцию ‘+=’.

String& String:: operator +=(String & s2)

{char *t = new char[len + 1];

strcpy(t, line); delete [ ]line;

len += s2.len; line = new char[len + 1];

strcpy(line, t); strcat(line, s2.line);

delete [ ] t;

return *this;

}

Тогда в примере из п.5 вместо оператора

String *s3 = new String(s1.Plus(s2));

можно записать

String *s3 = new String(s1 += s2);

И еще пример использования.

String s(«Студент »), r(«Петров »);

s += r; // s = «Студент Петров»

В классе String определим функцию сравнения двух строк.

int String:: EqStr(String &s)

{if (strcmp(line, s.line)) return 0; // строки не равны

return 1; // строки равны

}

Использовать ее можно так.

String s1(“Иванов”), s2(“Петров”);

if (s1.EqStr(s2)) cout << ”Строки равны”;

else cout << ”Строки не равны”;

Но было бы нагляднее для сравнения строк использовать операцию = =. Перегрузим ее для класса String.

int String:: operator = =(String & s)

{ if (strcmp(line, s.line)) return 0; // также как и в функции EqStr( )

return 1;

}

Cравнение теперь выглядит привычнее:

if (s1== s2) cout << ”\n Строки равны”;

else {s1.Print( ); cout << ” – это не “;s2.Print( );} //”Иванов – это не Петров”

Формат перегрузки одноместной операции имеет вид

тип_возвращаемого_значения operator @(пусто)

{тело_операции},

где @ – знак операции.

Напишем в качестве примера операцию реверса строки, т.е. перестановки символов в обратном порядке.

String String:: operator ~( )

{int i; char t;

for(i = 0; i < len / 2; i++)

t = line[i], line[i] = line[len – i –1], line[len – i – 1] = t;

return *this;

}

С помощью двух этих операций решим задачу: является ли слово «перевертышем».

void main( )

{String s1(“шалаш”);

String s2 = s1; // Работает конструктор копирования

s1.Print( );

if (s1 == ~s2) cout << ” – перевертыш”;

else cout << ” – не перевертыш”;

}

Правила перегрузки:

  1. При перегрузке операции, как член-функции класса, двуместная операция имеет один аргумент, одноместная – ни одного;

  2. Знак одноместной операции может быть перегружен только как одноместный, а двуместной – только как двуместный;

  3. Наряду с обычным использованием перегруженного знака

obj1 @ obj2 для двуместной

и

@ obj для одноместной

он может использоваться как член-функция класса

obj1.operator @(obj2)

и

obj.operator @()

  1. Нельзя перегружать операции для стандартных типов данных. Например, + для массивов, определенных, как int * a или int a[20].

  2. Нельзя перегружать операции

:: . ?: sizeof

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