Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по прогр.ч.2.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
293.89 Кб
Скачать

Лекция 5

Передача объектов функциям по значению

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

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

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

Пример

#include <iostream.h>

class MyClass

{int value;

public:

MyClass(int i)

{value=i;}

int getvalue()

{return value;}

void setvalue(int i)

{value=i;}

};

//внешние функции

void display(MyClass ob)

{cout<<ob.getvalue()<<”\n’;}

void change(MyClass ob)

{ob.setvalue(100);

cout<<”Значение объекта ob в функции change():”;

display(ob);

}

void main()

{MyClass a(10);

cout<<”Значение объекта а до функции change():”;

display(a);

change(a);

cout<<”Значение объекта а после функции change():”;

display(f);

}

Результат

Значение объекта а до функции change():10

Значение объекта ob в функции change():100

Значение объекта а после функции change():10

Изменение значения поля value объекта ob в функции change() не влияет на объект а, передаваемый в функцию change() в теле главной функции main().

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

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

Пример

#include <iostream.h>

class M

{int value;

public:

M(int i)

{value=i;

cout<<»В конструкторе.\n”;}

~M()

{cout<<”Разрушение объекта.\n”;}

int getvalue()

{return value;}

};

//Внешняя функция

void output(M ob)

{cout<<ob.getvalue()<<’\n’;}

void main()

{M a(10);

output(a);

}

Результат

В конструкторе.

10

Разрушение объекта.

Разрушение объекта.

В этом примере два обращения к деструктору: при выходе из функции output() и при разрушении объекта а в функции main().

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

Передача объектов функциям по ссылке

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

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

копии.

Рассмотрим пример передачи объекта в функцию по ссылке.

#include <iostream.h>

class M

{int value;

public:

M(int i)

{value=i;

cout<<”В конструкторе.\n”;}

~M()

{cout<<”Разрушение объекта.\n”;}

int getvalue()

{return value;}

void setvalue(int i)

{value=i;}

};

//Внешние функции

void display(M &ob)

{cout<<ob.getvalue()<<’\n’;}

void change(M& ob)

{ob.setvalue(500);}

void main()

{M a(100);//создание объекта а и инициализация поля value значением 100

display(a);

change(a);//запись в поле value объекта а значения 500

display(a);

}

Результат

В конструкторе.

100

500

Разрушение объекта.

В этой программе создается и разрушается только один объект а.

При передаче объектов по значению могут возникать побочные эффекты.

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

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

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