Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

Статическая переменная—член существует в единственном экземпляре для класса — такие переменные являются «переменными класса», а не «переменными экземпляра». Каждая статическая переменная—член должна определяться в файле .cpp (но без повторения ключевого слова static). Например:

#include "truck.h"

int Truck::counter = 0;

Если этого не сделать, компоновщик выдаст сообщение об ошибке из-за наличия «неразрешенного символа». Обращаться к статической функции instanceCount можно за пределами класса, указывая имя класса перед ее именем. Например:

01 #include <iostream>

02 #include "truck.h"

03 using namespace std;

04 int main

05 {

06 Truck truck1;

07 Truck truck2;

08 cout << Truck::instanceCount << " equals 2" << endl;

09 return 0;

10 }

Указатели

Указатель

в С++ — это переменная, содержащая не сам объект, а адрес памяти, где располагается объект. Java и C# имеют аналогичную концепцию «ссылки» при другом синтаксисе. Мы начнем с рассмотрения придуманного нами примера, иллюстрирующего применение указателей:

01 #include "point2d.h"

02 int main

03 {

04 Point2D alpha;

05 Point2D beta;

06 Point2D *ptr;

07 ptr = &alpha;

08 ptr->setX(1.0);

09 ptr->setY(2.5);

10 ptr = &beta;

11 ptr->setX(4.0);

12 ptr->setY(4.5);

13 ptr = 0;

14 return 0;

15 }

В этом примере используется класс Point2D из предыдущего подраздела. В строках 4 и 5 определяется два объекта типа Point2D. Эти объекты инициализируются в значение (0, 0) стандартным конструктором Point2D.

В строке 6 определяется указатель на объект Point2D. Для обозначения указателя здесь используется звездочка перед именем переменной. Поскольку мы не инициализируем указатель, он будет содержать произвольный адрес памяти. Эта ситуация изменяется в строке 7, в которой адрес alpha присваивается этому указателю. Унарный оператор & возвращает адрес памяти, где располагается объект. Адрес обычно представляет собой 32-битовое или 64-битовое целое число, задающее смещение объекта в памяти.

В строках 8 и 9 мы обращаемся к объекту alpha с помощью указателя ptr. Поскольку ptr является указателем, а не объектом, необходимо использовать оператор – > (стрелка) вместо оператора . (точка).

В строке 10 указателю присваивается адрес beta. С этого момента любая выполняемая нами операция с этим указателем будет воздействовать на объект beta.

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

значение 0 (или символическую константу NULL, которая разворачивается в 0). Попытка применения нулевого указателя приведет к краху приложения с выводом такого сообщения об ошибке, как «Segmentation fault» (ошибка сегментации), «General protection fault» (общая ошибка защиты) или «Bus error» (ошибка шины). Применяя отладчик, можно найти строку программного кода, которая приводит к краху.

В конце функции объект alpha содержит пару координат (1.0, 2.5), а объект beta — (4.0,4.5).

Указатели часто используются для хранения объектов, память для которых выделяется динамически с помощью оператора new. Используя жаргон С++ можно сказать, что эти объекты распределяются в «куче», в то время как локальные переменные (т.е. переменные, определенные внутри функции) хранятся в «стеке».

Ниже приводится фрагмент программного кода, иллюстрирующий динамическое распределение памяти при помощи оператора new:

01 #include "point2d.h"

02 int main

03 {

04 Point2D *point = new Point2D;

05 point->setX(1.0);

06 point->setY(2.5);

07 delete point;

08 return 0;

09 }

Оператор new возвращает адрес памяти для нового распределенного объекта. Мы сохраняем адрес в переменной указателя и обращаемся к объекту через этот указатель. Поработав с объектом, мы возвращаем занимаемую им память, используя оператор delete. В отличие от Java и C#, сборщик мусора отсутствует в С++; динамически распределяемые объекты должны явно освобождать занимаемую ими память при помощи оператора delete, когда они становятся больше ненужными. В главе 2 описывается механизм родственных связей Qt, который значительно упрощает управление памятью в программах, написанных на С++.

Если не вызвать оператор delete, память остается занятой до тех пор, пока не завершится программа. Это не создаст никаких проблем в приведенном выше примере, потому что память выделяется только для одного объекта, однако в программе, в которой постоянно создаются новые объекты, это может привести к нехватке машинной памяти. После удаления объекта переменная указателя по-прежнему будет хранить адрес объекта. Такой указатель является «повисшим указателем» и не должен использоваться для обращения к объекту. Qt предоставляет «умный» указатель QPointer<T>, который автоматически устанавливает себя в 0, если удаляется объект QObject, на который он ссылается.

В приведенном выше примере мы вызывали стандартный конструктор и функции setX и setY для инициализации объекта. Вместо этого можно было использовать конструктор с двумя параметрами:

Point2D *point = new Point2D(1.0, 2.5);

Кроме того, мы могли бы распределить объект в стеке следующим образом:

Point2D point;

point.setX(1.0);

point.setY(2.5);

Распределенные таким образом объекты автоматически освобождаются в конце блока, в котором они появляются.

Поделиться:
Популярные книги

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Проблема майора Багирова

Майер Кристина
1. Спецназ
Любовные романы:
современные любовные романы
6.60
рейтинг книги
Проблема майора Багирова

Законы Рода. Том 13

Андрей Мельник
13. Граф Берестьев
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 13

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

О, Путник!

Арбеков Александр Анатольевич
1. Квинтет. Миры
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
О, Путник!

Прометей: каменный век

Рави Ивар
1. Прометей
Фантастика:
альтернативная история
6.82
рейтинг книги
Прометей: каменный век

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Цвет сверхдержавы - красный. Трилогия

Симонов Сергей
Цвет сверхдержавы - красный
Фантастика:
попаданцы
альтернативная история
8.06
рейтинг книги
Цвет сверхдержавы - красный. Трилогия

Болтливый мертвец

Фрай Макс
7. Лабиринты Ехо
Фантастика:
фэнтези
9.41
рейтинг книги
Болтливый мертвец

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь