Программирование >>  Расширенная версия языка c++ 

1 ... 44 45 46 [ 47 ] 48 49 50 ... 227


Глава 5 груэка функций 147

cou year \n;

date::date(char *str) {

sscarif(str, %d%*c%d%*c%d , smonth, sday, syear);

int main () {

использование конструктора для даты в виде строки date sdate( 11/1/92 );

использование конструктора для даты в виде трех целых date idate(ll, 1, 92) ;

idate,5how()f

return 0;

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

привлекательной.

Хотя конструктор можно перегружать любое количество раз, лучше этим не злоупотреблять. С точки зрения стилистики, конструктор имеет смысл перегружать только тогда, когда такая перегрузка позволяет адаптировать программу к часто встречающимся ситуациям. Например, еще одна перегрузка конструктора date() для ввода трех восьмеричных целых вряд ли будет иметь какой-то смысл. Однако перегрузка конструктора date() для доступа к объекту типа time t (тип данных для хранения системных даты и времени) могла бы оказаться весьма полезной. (См. упражнения для проверки усвоения материала данной главы, где приведен именно такой пример.)

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

#include <iostreain> using namespace std;



myclass {

int x; public:

перегрузка конструктора двумя способами mycidiSii \} { x = 0; } нет инициализации myclass (int n) { x n; } инициализация

int ( return x; }

void setx(int n) { x = n; }

int mainO

myclass *p;

myclass ob(lO); инициализация отдельной неременной

p = ne s [10]; здесь инициализировать нельзя if(!p) {

cout -с; Ошибка выделения памяти\п ; . ,

return 1;

inti;

инициализация всех элементов значением ob for(i=U, i<10; i++) p[i] = ob;

for (1=0; i<lC; i+-f-) { - :

cou [ i p[i].getx();

cout

) -

return 0;

1

Без перегруженной версии конструктора ass(), в которой отсутствует инициализация, оператор new при компиляции вызвал бы ошибку.

УпйаЖнени!

1. Дано неполное определение класса:

class {

char *р;

int len; -

public:

char *getstring() { return p; } int { return len; }



5.2. Создание и использование конструкторов копий .

Одной из важнейших форм перегруженного конструктора является конструктор копий (copy constructor). Как показано в многочисленных примерах из предытдущих глав, передача объектов функциям и их возвращение из функций могут привести к разного рода проблемам. В этом разделе вы что одним из способов обойти эти проблемы является определение конструктора копий.

Для начала давайте обозначим проблемы, для решения которых предназначен конструктор копий. Когда объект передается в функцию, делается поразрядная (т. е. точная) копия этого объекта и передается тому параметру функции, который получает объект. Однако бывают ситуации, в которых такая точная копия объекта нежелательна. Например, если объект содержит указатель на выделенную область памяти, то в копии указатель будет ссылаться на ту же самую область памяти, на которую ссылается исходный указатель. Следовательно, если копия меняет содержимое области памяти, то эти изменения коснутся также и исходного объекта! Кроме того, когда выполнение функции завершается, копия удаляется, что приводит к вызову деструктора этой копии. Вызов деструктора может привести к нежелательным побочным аффектам, которые в дальнейшем повлияют на исходный

объект.

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

хранения возвращаемого функцией значения. (Это происходит автоматиче-

Добавьте в это определение два конструктора. В первом не должно быть параметров. Он должен выделять 255 байтов памяти (с помощью оператора new), инициализировать эту память нулевой строкой и устанавливать переменную len равной 255. Во втором конструкторе должно быть два параметра. Первый - это строка, используемая при инициализации, второй - число выделяемых байтов. Во второй версии конструктора должно выделяться заданное количество памяти, в которую должна помещаться копия строки. Необходимо реализовать полный контроль границ массива и, разработав

короткую программу вывода, показать, что оба конструктора работают так, как это было задумано.

2. В главе 2, раздел 2.1, упражнение 2 вы создали эмулятор секундомера. Модифицируйте ваше решение так, чтобы в классе stopwatch был и конструктор без параметров (как это уже сделано) и его перегруженная версия для доступа к системному времени через стандартную функцию с1оск(). Покажите, что внесенные изменения работают.

3. Подумайте о каким образом перегруженный конструктор может быть

полезен для ваших собственных программных задач.



1 ... 44 45 46 [ 47 ] 48 49 50 ... 227

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика