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

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

Жанры

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

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

Шрифт:

Объявленные таким образом переменные ведут себя как элементарные типы Java и C# (такие, как int и double). Например, при использовании оператора присваивания копируется содержимое переменной, а не ссылка на объект. И если позже переменная будет модифицирована, значение всех других переменных, к которым присваивалась первая переменная, не изменится.

С++, как объектно—ориентированный язык, поддерживает наследование и полиморфизм. Для иллюстрации этих свойств мы рассмотрим пример абстрактного класса Shape (фигура) и подкласса Circle (окружность). Начнем с базового класса:

01 #ifndef SHAPE_H

02 #define SHAPE_H

03 #include "point2d.h"

04 class Shape

05 {

06 public:

07 Shape(Point2D center) { myCenter = center; }

08 virtual void draw = 0;

09 protected:

10 Point2D myCenter;

11 };

12 #endif

Определение

класса создается в заголовочном файле с именем shape.h. Поскольку в этом определении делается ссылка на класс Point2D, мы включаем заголовочный файл point2d.h.

Класс Shape не имеет базового класса. В отличие от Java и C#, в С++ не предусмотрен обобщенный класс Object, который наследуется всеми другими классами. Qt предоставляет QObject в качестве естественного базового класса для объектов всех типов.

Объявление функции draw имеет две интересные особенности. Она содержит ключевое слово virtual и завершается равенством = 0. Ключевое слово virtual означает, что данная функция может быть переопределена в подклассах. Подобно C# функции—члены в С++ по умолчанию не могут переопределяться. Странное приравнивание = 0 указывает на то, что данная функция — чисто виртуальная функция, которая не имеет реализации по умолчанию, и она должна быть реализована в подклассах. Концепция «интерфейса» в Java и C# соответствует в С++ классу, содержащему только чисто виртуальные функции.

Ниже приводится определение подкласса Circle:

01 #ifndef CIRCLE_H

02 #define CIRCLE_H

03 #include "shape.h"

04 class Circle : public Shape

05 {

06 public:

07 Circle(Point2D center, double radius = 0.5)

08 : Shape(center) {

09 myRadius = radius;

10 }

11 void draw {

12 // здесь выполняются какие-то действия

13 }

14 private:

15 double myRadius;

16 };

17 #endif

Класс Circle наследует класс Shape в открытой форме, т.е. все открытые члены класса Shape остаются открытыми в Circle. С++ поддерживает также защищенное и закрытое наследование, которое ограничивает доступ к открытым и защищенным членам базового класса.

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

функции мы инициализируем переменную—член myRadius. Инициализацию этой переменной можно было сделать в той же строке, где инициализируется конструктор базового класса:

Circle(Point2D center, double radius = 0.5)

: Shape(center), myRadius(radius) { }

С другой стороны, С++ не позволяет инициализировать переменную—член в определении класса, поэтому следующий программный код неверен:

// НЕ БУДЕТ КОМПИЛИРОВАТЬСЯ

private:

double myRadius = 0.5;

};

Сигнатура функции draw совпадает с сигнатурой виртуальной функции draw, определенной в классе Shape. Она здесь переопределяется и будет вызываться полиморфно, когда draw вызывается экземпляром Circle через ссылку или указатель на Shape. С++ не имеет ключевого слова override, доступного в C#. С++ также не имеет ключевых слов super и base, ссылающихся на базовый класс. Если требуется вызвать базовую реализацию функции, можно перед именем функции указать имя базового класса и оператор ::. Например:

01 class LabeledCircle : public Circle

02 {

03 public:

04 void draw {

05 Circle::draw;

06 drawLabel;

07 }

08 };

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

class DerivedClass : public BaseClass1, public BaseClass2, …,

public BaseClassN

{

};

По умолчанию функции и переменные, объявленные в классе, связываются с экземплярами этого класса. Мы можем объявлять статические функции—члены и статические переменные—члены, которые могут использоваться без экземпляра. Например:

01 #ifndef TRUCK_H

02 #define TRUCK_H

03 class Truck

04 {

05 public:

06 Truck { ++counter; }

07 ~Truck { --counter; }

08 static int instanceCount { return counter; }

09 private:

10 static int counter;

11 };

12 #endif

Статическая переменная—член счетчика counter отслеживает количество экземпляров truck, которые существуют в любой момент времени. Конструктор truck его увеличивает на единицу. Деструктор, опознаваемый по префиксу ~, уменьшает счетчик на единицу. В С++ деструктор автоматически вызывается, когда статически распределенная переменная выходит из области видимости или когда удаляется переменная, память для которой выделяется при помощи оператора new. Это аналогично тому, что делается в методе finalize в Java, за исключением того, что мы можем рассчитывать на его вызов в определенный момент времени.

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

Я царь. Книга XXVIII

Дрейк Сириус
28. Дорогой барон!
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Я царь. Книга XXVIII

Полигон

Гостева Ирина
S.T.A.L.K.E.R.
Фантастика:
боевая фантастика
7.78
рейтинг книги
Полигон

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

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

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

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

Целеполагание

Владимиров Денис
4. Глэрд
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Целеполагание

Неведомые дороги (сборник)

Кунц Дин Рей
Фантастика:
ужасы и мистика
8.00
рейтинг книги
Неведомые дороги (сборник)

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Кодекс Охотника. Книга VII

Винокуров Юрий
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Кодекс Охотника. Книга VII

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Мастер решений

Земляной Андрей Борисович
3. Специалист по выживанию
Фантастика:
боевая фантастика
космическая фантастика
6.20
рейтинг книги
Мастер решений

Натиск

Осадчук Алексей Витальевич
12. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
6.20
рейтинг книги
Натиск

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4