Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Использование new delete для реализации массивов




Оператор new позволяет выделять память под массивы. Он возвращает

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

k=3;

int *p[]=new int[k][5]; // ошибка cannot convert from 'int (*)[5]' to 'int *[]'

int (*p)[5]=new int[k][5]; // верно

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

int *a = new int (10234);

Этот параметр нельзя использовать для инициализации массивов. Однако

на место инициализирующего значения можно поместить через запятую список

значений, передаваемых конструктору при выделении памяти под массив (мас-

сив новых объектов, заданных пользователем). Память под массив объектов

может быть выделена только в том случае, если у соответствующего класса

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

class matr

{ int a;

float b;

public:

matr(){}; // конструктор по умолчанию

matr(int i,float j): a(i),b(j) {}

~matr(){};

};

int main()

{ matr mt(3,.5);

matr *p1=new matr[2]; // верно р1 − указатель на 2 объекта

matr *p2=new matr[2] (2,3.4); // неверно, невозможна инициализация

matr *p3=new matr (2,3.4); // верно р3 – инициализированный объект

}

 

class A

{ int i; // компонента-данное класса А

public:

A(){} // конструктор класса А

~A(){} // деструктор класса А

};

int main()

{ A *a,*b; // описание указателей на объект класса А

float *c,*d; // описание указателей на элементы типа float

a=new A; // выделение памяти для одного объекта класса А

b=new A[3]; // выделение памяти для массива объектов класса А

c=new float; // выделение памяти для одного элемента типа float

d=new float[4]; // выделение памяти для массива элементов типа float

delete a; // освобождение памяти, занимаемой одним объектом

delete [] b; // освобождение памяти, занимаемой массивом объектов

delete c; // освобождение памяти одного элемента типа float

delete [] d; } // освобождение памяти массива элементов типа float

Организация внешнего доступа к локальным компонентам класса(friend)

Мы уже познакомились с основным правилом ООП – данные (внутренние

переменные) объекта защищены от воздействий извне и доступ к ним можно

получить только с помощью функций (методов) объекта. Но бывают такие слу-

чаи, когда нам необходимо организовать доступ к данным объекта, не исполь-

зуя его интерфейс (функции). Конечно, можно добавить новую public-функцию

к классу для получения прямого доступа к внутренним переменным. Однако в

большинстве случаев интерфейс объекта реализует определенные операции, и

новая функция может оказаться излишней. В то же время иногда возникает не-

обходимость организации прямого доступа к внутренним (локальным) данным

двух разных объектов из одной функции. При этом в С++ одна функция не мо-

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

Для реализации этого в С++ введен спецификатор friend. Если некоторая

функция определена как friend-функция для некоторого класса, то она:

- не является компонентой-функцией этого класса;

- имеет доступ ко всем компонентам этого класса (private, public и protected).

Ниже рассматривается пример, когда внешняя функция получает доступ к

внутренним данным класса.

 

#include <iostream>

using namespace std;

class kls

{ int i,j;

public:

kls(int i,int J): i(I),j(J) {} // конструктор

int max() {return i>j? i: j;} // функция-компонента класса kls

friend double fun(int, kls&); // friend-объявление внешней функции fun

};

double fun(int i, kls &x) // внешняя функция

{ return (double)i/x.i;

}

main()

{ kls obj(2,3);

cout << obj.max() << endl;

сout << fun(3,obj) << endl;

return 1;

}

 

 

Ссылки.Параметры ссылки

В С(С++) известны три способа передачи данных в функцию: по значе-

нию, посредством указателя и используя ссылки. тип & имя_ссылки = инициализатор.

Ссылку нельзя объявить без ее инициализации. То есть ссылаться всегда

можно на некоторый существующий объект. Можно выделить следующие раз-

личия ссылок и указателей. Во-первых, невозможность существования нулевых

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

передаваемых в нее параметров, то в языке С они должны быть объявлены либо

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

нее указатели на эти переменные. В С++ аргументы в функцию можно переда-

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

ром ставится знак &.

void fun1(int,int);

void fun2(int &,int &);

int main()

{ int i=1,j=2; // i и j – локальные параметры

cout << "\n адрес переменных в main() i = "<<&i<<" j = "<<&j;

cout << "\n i = "<<i<<" j = "<<j;

fun1(i,j);

cout << "\n значение i = "<<i<<" j = "<<j;

fun2(i,j);

cout << "\n значение i = "<<i<<" j = "<<j;

}

void fun1(int i,int j)

{ cout << "\n адрес переменных в fun1() i = "<<&i<<" j = "<<&j;

int a; // при вызове fun1 i и j из main() копируются

a=i; i=j; j=a; // в стек в переменные i и j при возврате в main()

} // они просто теряются

void fun2(int &i,int &j)

{ cout << "\n адрес переменных в fun2() i = "<<&i<<" j = "<<&j;

int a; // здесь используются ссылки на переменные i и j из

a=i; i=j; j=a; } // main() (вторые их имена) и таким образом действия

// в функции производятся с теми же переменными i и j

 

 

 

 

Ссылки.Независимые ссылки

В языке С++ ссылки могут быть использованы не только для реализации

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

грамме наряду с обычными переменными, например:

#include <iostream>

using namespace std;

int main()

{ int i=1;

int &j=i; // j – ссылка (второе имя) переменной i

cout << "\n адрес переменных i = "<<&i<<" j = "<<&j;

cout << "\n значение i = "<<i<<" j = "<<j;

j=5; //

cout << "\n адрес переменных i = "<<&i<<" j = "<<&j;

cout << "\n значение i = "<<i<<" j = "<<j;

return 0;

}

В результате работы программы будет получено:

адрес переменных i = 0xадрес1 j = 0xадрес2

значение i = 1 j = 1

адрес переменных i = 0xадрес1 j = 0xадрес2

значение i =5 j = 5

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

сваивается адрес ранее созданного объекта i. Далее j может быть использовано

как второе имя i.

 

 





Поделиться с друзьями:


Дата добавления: 2016-07-29; Мы поможем в написании ваших работ!; просмотров: 493 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Настоящая ответственность бывает только личной. © Фазиль Искандер
==> читать все изречения...

2313 - | 2041 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.008 с.