Читаем Освой самостоятельно С++ за 21 день. полностью

Следующий цикл (строки 31—35) выводит на экран все значения объектов, на которые делаются ссылки в массиве. Обращение к указателю выполняется с помощью индекса: Family[i]. После того как элемент массива установлен, следует вызов метода GetAge.

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

Объявление массивов в области динамического обмена

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

CAT *Family = new CAT[500];

Указатель Family будет содержать адрес в динамической области первого элемента массива из пятисот объектов класса CAT. Другими словами, в указателе представлен адрес объекта Family[0].

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

CAT *Family = new CAT[500];

CAT *pCat = Family; // pCat указывает на Family[0]

pCat->SetAge(10); // присваивает Family[0] значение 10

pCat++; // переход к Family[1]

pCat->SetAge(20); // присваивает Family[1] значение 20

В данном примере объявляется новый массив из 500 объектов класса CAT и возвращается указатель на первый элемент этого массива. Затем, используя это указатель и метод SetAge, объявленный в классе CAT, первому объекту массива присваивается

значение 10. Переход к следующему объекту массива осуществляется за счет приращения адреса в указателе на массив, после чего тем же способом присваивается значение 20 второму объекту массива.

Указатель на массив или массив указателей

Рассмотрим следующие три объявления:

1: Cat Family0ne[500];

2: CAT >> FamilyTwo[500];

3: CAT * FamilyThree = new CAT[500];

В первом случае объявляется массив FamilyOne, содержащий 500 объектов типа CAT. Во втором случае — массив FamilyTwo, содержащий 500 указателей на объекты класса CAT, и в третьем случае — указатель FamilyThree, ссылающийся на массив из 500 объектов класса CAT.

В зависимости от того, какое объявление используется в программе, принципиально меняются способы управления массивом. Как ни странно, но указатель FamilyThree по сути своей гораздо ближе к массиву FamilyOne, но принципиально отличается от массива указателей FamilyTwo.

Чтобы разобраться в этом, следует внимательно рассмотреть, что содержат в себе все эти переменные. Указатель на массив FamilyThree содержит адрес первого элемента массива, но ведь это именно то, что содержит имя массива FamilyOne.

Имена массивов и указателей

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

CAT Family[50];

создается указатель Family на адрес первого элемента массива &Family[0].

В программе допускается использование имен массивов как константных указателей и наоборот. Таким образом, выражению Family + 4 соответствует обращение к пятому элементу массива Family[4].

Компилятор выполняет с именами массивов те же математические действия сложения, инкремента и декремента, что и с указателями. В результате операция Family + 4 будет означать не прибавление четырех байтов к текущему адресу, а сдвиг на четыре объекта. Если размер одного объекта равен четырем байтам, то к адресу в имени массива будут добавлены не 4, а 16 байт. Если в нашем примере каждый объект класса CAT содержит четыре переменные-члена типа long по четыре байта каждая и две переменные-члена типа short по два байта каждая, то размер одного элемента массива будет равен 20 байт и операция Family + 4 сдвинет адрес в имени указателя на 80 байт.

Объявление массива в динамической области памяти и его использование показано в листинге 12.7.

Листинг 12.7. Создание массива с использованием ключевого слова new

1: // Листинг 12.7. Массив в динамической области памяти

2:

3: #include

4:

5: class CAT

6: {

7:    public:

8:       CAT { itsAge = 1; itsWeight=5; }

9:       ~CAT;

10:      int GetAge const { return itsAge; }

11:      int GetWeight const { return itsWeight; }

12:      void SetAge(int age) { itsAge = age; }

13:

14:   private:

15:      int itsAgo;

16:      int itsWeight;

17: };

18:

19: CAT::~CAT

20: {

21:    // cout << "Destructor called!\n";

22: }

23:

24: int main

25: {

26:    CAT * Family = new CAT[500];

27:    int i;

28:

29:    for (i = 0; i < 500; i++)

30:    {

31:       Family[i].SetAge(2*i +1);

32:    }

33:

34:    for (i = 0; i < 500; i++)

35:    {

36:       cout << "Cat #" << i+1 << ": ";

37:       cout << Family[i].GetAge << endl;

38:    }

39:

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

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

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT