Вход/Регистрация
QT 4: программирование GUI на С++
вернуться

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

Шрифт:

Класс 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, за исключением того, что мы можем рассчитывать на его вызов в определенный момент времени.

  • Читать дальше
  • 1
  • ...
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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