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

 

С++. Классы. Механизмы наследования. Объектные типы

Терминология объектно-ориентированного программирования
Объектно-ориентированное программирование позволяет оперировать в терминах классов: определять классы, конструировать производные классы, создавать объекты, принадлежащие классу, - экземпляры класса.
Сначала в некоторых языках программирования появился тип struct, расширением которого стал тип class.
Класс определяет данные (переменные) и поведение (методы). Данные и методы класса также называют членами класса. Класс рассматривается как определяемый пользователем тип данных.
Объектом называется экземпляр некоторого класса. Объект создается как переменная типа класса, которая используется для доступа к данным - членам класса и для вызова методов - членов класса.
Наследованием называется механизм, позволяющий производному классу наследовать структуру данных и поведение другого класса, а также наследовать поведение, объявленное в интерфейсах и абстрактных классах.
Наследование позволяет определять новые классы в терминах существующих классов.
В объектно-ориентированном программировании наследование может быть:

  • множественным, позволяющим производному классу наследоваться одновременно от нескольких классов (например, так реализован механизм наследования в С++);
  • простым, когда производный класс имеет только один наследуемый класс (например, так реализованы языки Java и Object Pascal).

Наследуемый класс принято называть базовым классом, или родительским классом (классом - предком, суперклассом).
Производный класс, наследующий структуру данных и поведение своего базового класса, иногда также называется дочерним классом (классом - потомком, подклассом).
В производном классе можно переопределять методы базового класса и добавлять новые методы. Непосредственным базовым классом называется класс, от которого порожден производный класс следующего уровня иерархии:


   А   

Базовый класс класса С и непосредственный базовый класс класса B

   ⇓   

 

   B   

Непосредственный базовый класс класса C

   ⇓   

 

   C   

Производный класс

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

Объектно-ориентированное программирование на языке С++

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

  • Visual Studio.NET;
  • С++ Builder.

Среда программирования Visual Studio.NET предназначена для создания приложений не только на языке С++, но и на таких популярных языках, как C# и Visul Basic. Иногда для сокращения говорят, что проектирование приложений на C++ в Visual Studio.NET реализуется средой Visual C++.
Visual C++ позволяет разрабатывать приложения как в терминах традиционного модульного программирования, так и с применением объектно-ориентированного программирования.

Структура приложения на языке С++

Приложение состоит из модулей трансляции - файлов исходного кода на языке С++. Каждый модуль трансляции представляется файлом реализации класса и заголовочным файлом (компилятор позволяет записывать всю информацию - объявление и реализацию, в один файл, но это оправданно только для маленьких программ).
Проектом в терминологии Visual C++ называется совокупность всех модулей трансляции, файлов ресурсов и описания конфигурации.
Разработка любого приложения в Visual C++ начинается с создания проекта. Visual Studio.NET предоставляет шаблоны для создания различных видов приложений (консольные приложения, MFC-приложения, DLL-библиотеки, приложения управляемого кода и т.п.).
Консольное приложение - это приложение, не использующее Windows-окна для обработки сообщений от пользователя. Точкой входа в консольное приложение в языке С++ является метод main.
После того как создан шаблон приложения заданного вида, информация обо всех файлах проекта отображается в окне проектов среды Visual C++.
Заголовочный файл содержит объявления используемых данных. Язык C++ поддерживает соглашение о раздельной компиляции: каждый С++-модуль можно компилировать отдельно. Для того чтобы несколько модулей могли использовать одни и те же данные, объявление этих данных выносят в заголовочный файл. Принято, что имя заголовочного файла имеет расширение h.
Все подключаемые к модулю заголовочные файлы указываются в начале модуля директивой препроцессора #include.
Например:

#include "stdafx.h"
#include <iostream>

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

  • в двойных кавычках - в этом случае препроцессор сначала выполняет поиск данного файла в том же каталоге, в котором расположен файл, содержащий директиву препроцессора #include, а затем в каталогах, определяемых опцией компиляции и переменной среды INCLUDE.
  • в угловых скобках - при этом исключается поиск имени файла в том же каталоге, в котором расположен файл, содержащий директиву препроцессора #include.

Файл, содержащий реализацию методов, объявленных в заголовочном файле, иногда называется исходным файлом.
Каждая программа должна иметь точку входа и может содержать описание одного или нескольких классов.
Точкой входа в программу в приложении, формируемом по шаблону в среде Visual C++, является метод _tmain, заменяемый при компиляции на метод main.
Минимальной программой на С++ является следующий код:

int main() {}

Эта программа определяет функцию с именем main, которая не использует параметров и не выполняет никаких действий.
Тело метода в языке С++ указывается в фигурных скобках. Перед именем метода указывается тип возвращаемого значения. Если метод не возвращает никакого значения, то его тип обозначается ключевым словом void.

Объявление и реализация класса в языке С++

Создаваемый класс должен быть объявлен и реализован.
Объявление класса в языке С++ может иметь следующее формальное описание:

class имя_класса : список_базовых_классов {
public:    // Модификатор доступа относится
           // ко всем перечисленным после 
           // него членам до следующего 
           // модификатора доступа
    // Объявление общедоступных членов класса
 
protected:
    // Объявление членов класса, доступных 
    // только для производных классов
 
private:
    // Объявление защищенных членов класса
};

Список базовых классов указывается после имени класса через символ двоеточия (:), разделяется запятыми и может иметь модификаторы доступа.
Например:

class MyClass :  public ClassA, 
    public ClassB, private ClassC {};

В языке С++ считается, что если модификатор доступа для класса или члена класса не указан, то по умолчанию предполагается модификатор доступа private (защищенный доступ). Для членов структур, объявляемых ключевым словом struct, по умолчанию модификатор доступа предполагается равным public.
Модификатор доступа базового класса позволяет определить, какие переменные и методы базового класса будут доступны из производного класса. Модификатор доступа, указываемый перед именем базового класса, определяет следующие правила доступа к переменным и методам базового класса из производного класса:

  • public - в производном классе доступны все переменные и методы базового класса с модификаторами доступа public и protected, и эти члены класса имеют те же права доступа;
  • protected - члены базового класса с модификаторами доступа public и protected доступны как protected, а с модификатором доступа private - недоступны.
  • private - члены базового класса с модификаторами доступа public и protected доступны как private, а с модификатором доступа private - недоступны.

Например:

class BaseClass
{ public:
    int PublicFunc();    
 protected:
    int ProtectedFunc();
 private:
    int PrivateFunc();   
};
class DerivedClass1 : public BaseClass {
// Наследуемая функция PublicFunc доступна 
// как public
// Наследуемая функция ProtectedFunc 
// доступна как protected 
};
class DerivedClass2 : private BaseClass {
// Наследуемая функция PublicFunc доступна  
// как private
// Наследуемая функция ProtectedFunc 
// доступна как private
 };
int main() { }

В теле объявления класса указываются модификаторы доступа, описывающие права доступа для переменных и методов класса:

  • модификатор доступа относится ко всем перечисленным после него членам до следующего модификатора доступа;
  • один и тот же модификатор доступа может указываться несколько раз;
  • после модификатора доступа ставится символ двоеточие;
  • если модификатор доступа не указан, то по умолчанию предполагается private.

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

class A {      public:        int i;  Func1();}
A:: Func1() { return this->i; }  
    // this - указатель класса A

Конструкторы класса

Конструктором называется метод, вызываемый при создании объекта данного класса. Класс может иметь несколько конструкторов, отличающихся списком параметров.
Деструктором называется метод, вызываемый при разрушении объекта данного класса. Имена конструктора и деструктора совпадают с именем класса, но перед именем деструктора указывается символ ~.
При создании объектов последовательно вызываются конструкторы всех его базовых классов. Вызов деструкторов при уничтожении объекта происходит в обратном порядке.
Если конструктор базового класса имеет список параметров, то для его использования в производном классе следует создать конструктор производного класса с таким же списком параметров.
При создании нового класса среда Visual C++ автоматически создает заголовочный файл и файл реализации класса с конструктором и деструктором без параметров.

Создание объекта

Для создания объекта (экземпляра данного класса) следует объявить переменную типа указатель на класс, а затем создать объект, выполнив оператор new с указанием используемого конструктора.
Например:

A* ca;
ca= new A();

Эти же действия можно записать одним оператором.
Например:

A* ca= new A();

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

http://localhost:3232/img/empty.gifhttp://localhost:3232/img/empty.gifВложенные классы

Язык С++ допускает использование вложенных классов - внутри тела одного класса содержится объявление других классов.
Например:

class A
{
public:
   A(void);
   ~A(void);
   class B {   // Вложенный класс 
       B(void) {};  
       ~B(void) {};
char sStr2[3]; 
      };
 
};

Объектные типы

Тип данных всегда определяет размер памяти, которая будет выделена под переменную данного типа при ее создании.
При объявлении переменной объектного типа (типа класса) создаются переменные члены класса и вызывается конструктор класса. Производные типы на основе классов позволяют получать доступ к членам класса.
Переменная, объявленная как указатель на класс, применяется для доступа к методам и переменным членам класса. В следующей таблице приведен синтаксис, используемый при работе с указателями на члены класса.
Hапример:

#include <iostream.h>
class A        // Объявление класса A
{ public: int j1;
   A(void);
   ~A(void);};
void main() { 
int A::*pToj = &A::j1; 
    // Объявление производного типа pToj
    // как указателя на член класса j1 
A jA;                          
    // Объявление переменной объектного типа A
A *pjA = & jA;   
    // Объявление указателя на эту 
    // переменную (объект)
int j;
jA.*pToj = 123;    
    // Присваивание значения переменной 
    // jA::j1, используя * 
j = pjA ->*pToj; 
    // Получение значения, используя ->*
 std::cout << j << "\n";
}

Преобразование объектных типов

Указатель на класс может быть преобразован к указателю на базовый класс в двух случаях:

  • если базовый класс является доступным и преобразование однозначно;
  • если указано явное преобразование типа указателя.

Например:

class A           // А - базовый класс
{public:
    int a1;
    int Fa();
};
class B : public A     // В - производный класс
{public:
    int b1;
    int Fb();
};
B bObj;        // Объект типа B
A *pA = &bObj; 
    // Преобразование типа ограничивает 
   // доступ к членам класса B и 
   // разрешает доступ только к членам 
   // базового класса
B *pB = &bObj; 
    // Нет преобразования типа и 
   // следовательно разрешен доступ как 
   // к членам класса B, 
   // так и к членам класса А.
pA-> Fa ();    
    // Правильно: вызов функции члена класса A.
pB-> Fa ();    
    // Правильно: вызов функции, 
   //наследуемой от класса A
// Вызов pA-> Fb ();   ошибочен: функция Fb
// недоступна через указатель на базовый 
// класс А

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

Квалификация имен

Квалификация имен используется для однозначного понимания указываемого имени.
Для квалификации имени могут использоваться следующие операторы: :: (оператор принадлежности); . (оператор доступа к члену класса посредством имени); -> (оператор доступа к члену класса через указатель).

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика