Выбрать главу

// Одно из решений проблемы передачи объектов.

#include <iostream>

#include <cstdlib>

using namespace std;

class myclass {

  int *p;

 public:

  myclass(int i);

  ~myclass();

  int getval() { return *p; }

};

myclass::myclass(int i)

{

 cout << "Выделение памяти, адресуемой указателем p.\n";

 р = new int;

 *p = i;

}

myclass::~myclass()

{

 cout <<"Освобождение памяти, адресуемой указателем p.\n";

 delete p;

}

/* Эта функция HE создает проблем. Поскольку объект ob теперь передается по ссылке, копия аргумента не создается, а следовательно, объект не выходит из области видимости по завершении функции display().

*/

void display(myclass &ob)

{

 cout << ob.getval() << '\n';

}

int main()

{

 myclass a(10);

 display(a);

 return 0;

}

Результаты выполнения этой версии программы выглядят гораздо лучше предыдущих.

Выделение памяти, адресуемой указателем р.

10

Освобождение памяти, адресуемой указателем р.

Как видите, здесь деструктор вызывается только один раз, поскольку при передаче по ссылке аргумента функции display() копия объекта не создается.

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

Возвращение объектов функциями

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

// Использование функции, которая возвращает объект.

#include <iostream>

#include <cstring>

using namespace std;

class sample {

  char s[80];

 public:

  void show() { cout << s << "\n"; }

  void set(char *str) { strcpy(s, str); }

};

// Эта функция возвращает объект типа sample.

sample input()

{

 char instr[80];

 sample str;

 cout << "Введите строку: ";

  cin >> instr;

 str.set(instr);

 return str;

}

int main()

{

 sample ob;

 // Присваиваем объект, возвращаемый

 // функцией input(), объекту ob.

 ob = input();

 ob.show();

 return 0;

}

В этом примере функция input() создает локальный объект str класса sample, а затем считывает строку с клавиатуры. Эта строка копируется в строку str.s, после чего объект str возвращается функцией input() и присваивается объекту ob в функции main().