Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Magistr.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.85 Mб
Скачать
  1. Возвращение объектов из функций. Как осуществляется, возникающие проблемы и методы их устранения.

Функция может возвращать объект в точку вызова. В качестве примера рассмотрим программу: #include <iostream.h> class myclass { int i; public: void set_i(int n) {i=n;} int get_i() {return i;} }; myclass f(); // возвращение объекта типа myclass int main() { myclass o; о = f (); cout << о.get_i() << "\n"; return 0; } myclass f() { myclass x; x.set_i(1); return x; }

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

class Integer

{

private:

int value;

public:

Integer(int i): value(i)

{}

Integer& operator=(const Integer& right) {

//проверка на самоприсваивание

if (this == &right) {

return *this;

}

value = right.value;

return *this;

}

};

  1. Перегрузка конструкторов как осуществляется и зачем применяется.

Эта программа использует библиотечную функцию clock(), возвращающую число тиков, про­шедших с момента запуска программы. Поделив это значение на макрос CLK_TCK, получаем значение в секундах. Прототипы для clock() и CLK_TCK содержатся в заголовочном файле time.h. #include <iostream.h> #include <stdlib.h> #include <time.h> class timer { int seconds; public: / / секунды задаются строкой timer(char *t) { seconds = atoi(t); } // секунды задаются целым числом timer (int t) { seconds = t; } // время задается в минутах и секундах timer (int min, int sec) { seconds = min*60 + sec; } void run(); }; void timer::run() { clock_t t1, t2; t1 = t2 = clock () /CLK_TCK; while (seconds) { if (t1/CLK_TCK+1 <= (t2=clock())/CLK_TCK) { seconds--; t1 = t2; } } cout << "\a"; // звонок } int main() { timer a(10), b(20), c(1, 10); a.run (); // отсчитать 10 секунд b.run (); // отсчитать 20 секунд c.run (); // отсчитать 1 минуту, 10 секунд return 0; }

Как можно видеть, при создании объектов a, b и с внутри функции main() они получают началь­ное значение с использованием трех различных методов, поддерживаемых перегруженными кон­структорами. Каждый из них позволяет провести инициализацию для соответствующих данных.

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

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