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

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

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

Пример

class q

 {

int x[12]; // массив x с максимальной длиной ,равной 12

int n;.// действительное количество элементов

public:

q(int n1…..) {n=n1; ……}; /* конструктор, в котором передается действительное количество элементов массива x, которое используется при вводе и обработке; n1-параметр для передачи действительного количества элементов */

}; // конец определения класса

 

Недостатком этого метода является то, что при создании всех объектов этого класса для каждого объекта будет выделяться память для 12-ти элементов целого типа, а использоваться только часть этого массива; рабочий размер этого массива, например, определяется в конструкторе формальным параметром n1.

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

Способ 2а

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

Пример

#include<iostream.h>

#include <conio.h>

class q1

{

int *x; // указатель на массив целых чисел

int n; // количество элементов в массиве

public:

q1(int *y,int n1)/* конструктор, передающий массив y и количество n1 обрабатываемых элементов */

{ x=y; //присвоение адреса внешнего массива

  for(int i=0;i<n1;i++)

       {

       cout<<"x[i]="<<x[i]<<" y[i]="<<y[i]<<endl;/* распечатка передаваемого массива и массива объекта*/

       }

       n=n1; /* фиксация действительного размера массива */

} .// конец определения конструктора

}; // конец определения класса

int main() // главная функция

{ clrscr();

int f[4]={4,3,2,1};

q1 obj1(f,3); // задание в объекте адреса внешнего массива f

}// конец главной функции

 

 

Недостатком этого способа является то, что в этом случае данные объекта и данные внешней (главной) функции имеют одинаковые адреса (т. е. являются связанными по адресам); поэтому данные объекта фактически незащищены, хотя они имеют режим доступа private.

Способ 2б

 В рассматриваемом способе используется динамическая память для массива.

Для того, чтобы избежать указанного в способе 2а недостатка, необходимо реализовать следующий алгоритм:

- дать запрос на выделение собственной памяти для передаваемого массива. Это реализуется с помощью оператора new , который позволяет динамически выделить память соответствующего размера.

- переписать в эту память передаваемый массив.

В этом случае программы обработки по членам-функциям и внешним функциям будут разделены по адресам данных.

Пример

В данном случае используется та же структура объекта, что и в примере способа 2а.

#include<iostream.h>

#include <conio.h>

class q1

{

int *x; //указатель на массив целых чисел

int n;// действительное количество элементов в массиве

public:

q1(int *y,int n1)// конструктор для передачи n1 элементов целого типа

{ x=new int [n1]; /* запрос памяти для массива из n1 элементов целого типа*/

  for(int i=0;i<n1;i++)

       {

       x[i]=y[i];// передача i-го элемента

       cout<<"x[i]="<<x[i]<<" y[i]="<<y[i]<<endl;

       }

       n=n1;

}

}; // конец определения класса

int main()

{ clrscr();

int f[4]={4,3,2,1};

q1 obj1(f,3); /* в этом случае при исполнении конструктора выделяется память для трех элементов целого типа, в которую копируются три элемента внешнего массива f */

}

 

Примечание

Замечание о необходимости использования динамической памяти, конечно, справедливы и для  случая использования простых скалярных величин. Но особенно это актуально, как было уже сказано, для массивов.

 

Дата: 2019-03-05, просмотров: 214.