Главная страница
Навигация по странице:

  • Наследование

  • Класс в объектно – ориентированных языках программирования

  • Структура класса Класс включает две части: интерфейс

  • Формат определения класса С++

  • Реализация инкапсуляции через спецификаторы доступа Для обеспечения скрытия данных и поддержки инкапсуляции в классах С++ используются уровни доступа к членам класса: private

  • Глобальные и локальные классы Глобальные классы

  • Члены данных в классе 5.7.1 Переменные экземпляра

  • 5.7.2 Переменные класса – статические переменные

  • 5.8.1 Виды функций – членов класса Конструктор

  • Методы

  • Константные методы

  • 5.8.2 Место реализации функций - членов класса Функции - члены могут быть определены

  • 5.8.3 Функции члены класса inline (подстановки)

  • 5.8.4 Методы (функции – члены) экземпляра Это нестатические функции - члены. 5.8.4.1 Указатель this

  • 5.8.4.2 Перегрузка методов

  • 5.8.4.3 Функции – члены со спецификацией const

  • ООП. Пособие по ООП в С++. Создание сложных программных систем Объектно ориентированная технология


    Скачать 2.1 Mb.
    НазваниеСоздание сложных программных систем Объектно ориентированная технология
    Дата21.02.2022
    Размер2.1 Mb.
    Формат файлаpdf
    Имя файлаПособие по ООП в С++.pdf
    ТипАнализ
    #369034
    страница4 из 15
    1   2   3   4   5   6   7   8   9   ...   15
    Ограничение доступа – сокрытие отдельных элементов реализации абстракции.
    Необходимость ограничения доступа предполагает присутствие в абстракции (классе) двух частей:
    Интерфейс - доступных извне элементов реализации абстракции
    (состояния и поведения);
    Реализация – совокупность недоступных извне элементов реализации абстракции (внутренняя реализация абстракции и механизмы реализации ее поведения).
    Инкапсуляцияобъединение всех свойств объекта, определяющих его состояние и поведение в единую абстракцию и ограничение доступа к реализации. Суть инкапсуляции - доступ к данным разрешен только методам класса.
    Наследование – создание нового класса на основе отношения «общее - часть»
    Полиморфизм
    – переопределение наследниками методов выполняющих одну задачу, но по разному для разных классов иерархии.

    5.2
    Класс в объектно – ориентированных языках
    программирования
    В теории объектно - -ориентированного программирования класса определяет множество объектов, имеющих одинаковый набор свойств и поведение.
    В объектно – ориентированном программировании класс - инструмент построения новых типов
    – пользовательских, т.е. определяет пользовательский тип данных Этим типом так же удобно пользоваться, как и встроенными и использование пользовательского типа не должно отличаться от использования встроенных типов.
    Тип представляет в программе некоторое понятие, так тип int представляет целое знаковое число, а unsigned int – беззнаковое целое, а также набор операций, способы представления констант этого типа.
    Новый тип создается для того, чтобы представить в программе некоторое понятие, которое не может быть представлено встроенным типом.
    Очень удобно сопровождать программу, в которой типы хорошо представляют используемые в задаче понятия, задача и программа оперируют одинаковыми понятиями.
    Хорошо подобранное множество пользовательских типов делает программу более понятной и позволяет транслятору обнаруживать недопустимое использование объектов, которое в противном случае останется не выявленным до отладки программы.
    Главное назначение в определении нового типа в программе - это отделить несущественные детали реализации (например, расположение данных в объекте нового типа ) от тех его характеристик, которые существенны для правильного его использования (например, полный список функций, имеющих доступ к данным). Такое разделение обеспечивается тем, что вся работа со структурой данных и внутренние, служебные операции над нею доступны только через специальный интерфейс.
    Новый тип создается для того, чтобы представить в программе некоторое понятие, которое не может быть представлено встроенным типом.
    Очень удобно сопровождать программу, в которой типы хорошо представляют используемые в задаче понятия: задача и программа оперируют одинаковыми понятиями.
    Хорошо подобранное множество пользовательских типов делает программу более понятной и позволяет транслятору обнаруживать
    недопустимое использование объектов, которое в противном случае останется не выявленным до отладки программы.
    Класс это абстрактный тип данных, определяемый пользователем. Он представляет модель реального объекта через данные (состояние) и функции по обработке этих данных (поведение).
    5.3
    Структура класса
    Класс включает две части:
    интерфейс – внешнее устройство класса – операции доступные всем экземплярам класса – обязательства класса перед своими клиентами.
    Обеспечивает воздействие одного объекта на другой с целю передать сообщение. Главное в интерфейсе – объявление операций, поддерживаемых всеми экземплярами класса.
    Три части интерфейса:
    Закрытая (private) – члены класса доступны только методам этого класса, друзьям.
    Открытая(public) - члены класса доступны клиентам.
    Защищенная (protected) – члены класса доступны наследникам, друзьям.
    реализация – внутреннее устройство класса – реализация (определение функций) операций объявленных в интерфейсной части.
    Состояние объекта задается в его классе через определения констант или переменных, помещенных в закрытую или защищенные части класса.
    5.4
    Формат определения класса С++
    Реализация объектно – ориентированного подхода вС++ может быть выполнена на основе типа struct и на основе класса (class). Тип struct не поддерживает принцип наследования, а следовательно и принцип полиморфизма.
    Класс это абстрактный тип данных, определяемый пользователем. Он представляет модель реального объекта через данные (состояние) и функции по обработке этих данных (поведение).
    Членами класса являются:
    • Члены данных (поля данных) - это свойства или характеристики элемента класса - данные класса, реализующие состояние;
    • Члены функции (методы) – это функции класса, представляют поведение объектов класса.

    Состояние объекта определяют поля данных, например, компьютер включен или выключен.
    Формат объявления класса в С++. сlass имя класса
    {
    [private:]
    закрытые члены класса ] public:
    открытые члены класса (интерфейс класса)
    [protected:]
    защищенные члены класса ]
    };
    5.5 Реализация инкапсуляции через спецификаторы доступа
    Для обеспечения скрытия данных и поддержки инкапсуляции в классах
    С++ используются уровни доступа к членам класса:
    private - список полей и методов объявленных после спецификатора private будет доступен только методам этого класса и друзьям.
    public
    - члены класса доступные другим функциям и объектам программы.
    Методы этой части класса представляют интерфейс класса.
    protected – члены класса доступные в классе, наследникам, друзьям.
    Примечание. При объявлении класса, не обязательно объявлять три спецификатора доступа, и не обязательно их объявлять в таком порядке. Но лучше сразу определиться с порядком объявления спецификаторов доступа, и стараться его придерживаться.
    Ограничение доступа к членам класса предоставляет следующие преимущества:

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

    Программисту, использующему класс достаточно знать только объявления методов и их функционал.
    Пример определения типа на основе класса и struct struct Pupil
    { char Fam[20], Name[10]; unsigned short Nclass;
    unsigned char P; char Adress[40]; void input_pupil(); void out_pupil();
    };
    Реализация метода вне структуры void Pupil::input_pupil()
    { cout<<"Фамилия:"; cin>>Fam; cout<<"Имя:"; cin>>Name; cout<<"Номер класса:"; cin>>Nclass; cout<<"Пол:"; cin>>P; cout<<"Адрес:"; cin>>Adress;
    }
    Тип struct не имеет уровней защиты для своих членов. Они все имеют уровень защиты public – т.е. к членам структуры могут обращаться внешние функции.
    Определить тип Ученик на основе класса, включив две части в класс: данные и интерфейс. class CPupil
    { char Fam[20], Name[10]; unsigned short Nclass; unsigned char P; char Adress[40]; public:
    //интерфейс класса void input_pupil(); void out_pupil();
    };
    Реализация функций – членов вне класса выглядит так же, как и для структуры void СPupil::input_pupil()
    { cout<<"Фамилия:"; cin>>Fam; cout<<"Имя:"; cin>>Name; cout<<"Номер класса:"; cin>>Nclass; cout<<"Пол:"; cin>>P;
    cout<<"Адрес:"; cin>>Adress;
    }
    Внешним функция мдоступ к данным закрыт. void input_pupil(CPupil U)
    { cout<<"Фамилия:"; cin>>U.Fam; //ошибка
    }
    5.6
    Глобальные и локальные классы
    Глобальные классы – это классы, объявленные вне главного блока.
    Локальные классы - это классы, объявленные внутри любого блока функции или другом классе. Для них характерно:
    • Локальный класс не может иметь статических элементов.
    • Методы класса могут быть реализованы только внутри класса.
    Если один класс вложен в другой, то они не имеют каких-то особенных способов доступа к членам класса, для них также действуют общие правила доступа.
    5.7 Члены данных в классе
    5.7.1 Переменные экземпляра
    Могут быть представлены:
    • переменными любого типа, кроме типа этого же класса;
    • указателями, ссылки, в том числе и на этот класс;
    • переменными со спецификатором const, которые инициализируются один раз конструктором класса, их значения нельзя изменять;
    Примечание. Инициализация полей при описании не допускается.
    Имя класса принято начинать с большой буквы, последующие слова в имени также должны начинаться с большой буквы, например, ClassRectangl.
    Пример определения полей в гипотетическом классе X class X
    { static string s1; static const double pi=3.14; const int N=100; private: int x,y;
    double c,d; char *s2; int a[30]; int *b;
    X *myClass;
    //ссылка на объект класса
    X aa;
    // не верно: не может быть объектом этого класса
    };
    5.7.2 Переменные класса – статические переменные
    Это статические переменные в классе.
    Переменными со спецификатором static – это статические поля – общие для всех экземпляров класса, являются переменными класса, а не экземпляра.
    У каждого создаваемого объекта класса свои члены - данных – это переменные данного объекта, они могут быть изменены. Но в некоторых приложениях необходимо, чтобы в классе была определена переменная, общая для всех его объектов.
    Чтобы сделать переменную общую для всех объектов класса, ее надо объявить статической, она будет храниться в долговременной памяти и принадлежать классу, а не объекту.
    Например, как автоматизировать процесс формирования уникального для данного банка номера банковского счета, чтобы при создании нового объекта – нового счета – номер был определен программно. Т.е. у всех объектов Счет должна быть общая переменная, от значения которой будет создаваться номер счета, например увеличением этой переменной на 1.
    Определение класса лучше сохранить в заголовочном файле, а его реализацию в файле cpp. Для этого примера надо инициализировать статическую переменную и это лучше сделать в файле реализации.
    Файл "Bank.h" class
    Bank
    {
    //переменная для выделения каждому объекту своего номера счета
    //номер счета данного объекта int nAccountNumber;
    //текущий баланс double dBalance; protected: static int nNextAccountNumber; public:

    Bank()
    {
    //следующий номер счета nAccountNumber=++nNextAccountNumber;
    Cleare();
    //вызывает другой метод
    } void
    Cleare()
    { dBalance=0.0;
    } int get_nAccountNumber()
    { return nAccountNumber;
    }
    };
    Файл Bank.cpp
    #include
    "StdAfx.h"
    #include
    "Bank1.h"
    //инициализация статической переменной int
    Bank1::nNextAccountNumber=0;
    Основная программа
    #include
    "stdafx.h"
    #include

    #include
    "Bank.h" using namespace std; int main(
    int argc, _TCHAR* argv[])
    {
    Bank1 B1;//вызов конструктора по умолчанию
    B1.set_nNextAccountNumber(); std::cout<<
    "nNextAccountNumber B1="
    <Bank1 B2; std::cout<<
    "nNextAccountNumber B1="
    <}
    Результат

    Правила использования статических переменных
    1.
    Инициализировать в классе нельзя, это надо сделать в программе, лучше в файле реализации.
    2.
    Обращаться к полю через имя класса.
    3.
    Статическое поле будет создано в единственном числе, т.е. не будет создаваться для каждого объекта.
    4.
    Методы класса могут к ней обращаться.
    5.8
    Функции - члены в классе (методы)
    Это функции, реализующие:
    • выполнение операций над данными класса;
    • обеспечивающие обмен сообщениями между объектами классов приложения.
    Им разрешен доступ к членам – данным класса как к глобальным переменным, т.е. методы видят поля данных класса.
    5.8.1 Виды функций – членов класса
    Конструктор – метод, который создает экземпляр (объект класса) и инициализирует поля.
    Деструктор – метод, обеспечивающий удаление объекта. После удаления доступ к объекту закрыт.
    Методы – операции над объектами класса (вычисления на данных и изменение значений полей класса (get и set)).
    Дружественные функции – это функции, которым разрешен доступ к членам класса как к собственным переменным, но не являющиеся методами класса.
    Константные методы – имеют спецификатор const после списка параметров. Такой метод не может изменить состояние объекта, т.е. изменять значения полей.
    Статические методы – реализуют операции над статическими полями данных класса. Являются методами класса, а не экземпляра, в них не доступен указатель this.

    5.8.2 Место реализации функций - членов класса
    Функции - члены могут быть определены (реализованы) внутри класса или объявлены в классе.
    Реализация объявленных методов выполняется вне класса. При этом к имени метода приписывается префикс принадлежности имени (оператор видимости) Имя класса::Имя метода.
    Пример класса Рациональное число(РЧ)
    РЧ – это отношение числителя и знаменателя. В классе числитель и знаменатель представлены целыми числами, при этом знаменатель не равен нулю.
    Методы: сложение, вычитание, изменение числителя и знаменателя, наибольший общий делитель для сокращения дроби. Требуется контроль знаменателя. class Droby
    { private: int a,b; int Nod();
    //реализация вне класса public:
    Droby(int a1, int b1);
    //объявление void Add(Droby &d);
    //реализация вне класса void set_a(int a1){a=a1;} //реализация в классе void set_b(int b1){b=b1;} //реализация в классе int get_a(){return a;} //реализация в классе int get_b(){return b;} //реализация в классе
    Droby& Sub(Droby &d); //реализация вне класса
    };
    //реализация объявленных методов
    Droby::Droby(int a1, int b1)
    { a=a1; b=b1;int N=Nod();a= a/N; b= b/N;
    } int Droby::Nod()
    { if (a && !b || b && !a)

    { return a+b;
    } int a1=a, b1=b; while(a1!=b1)
    { if (a1>b1) a1=a1-b1; else b1=b1-a1;
    } return a1;
    } void Droby::Add(Droby &d)
    { int a1=a*d.b+b*d.a; b=b*d.b; a=a1; int N=Nod(); a=a/N; b=b/N;
    }
    Droby& Droby::Sub(Droby &d)
    {
    Droby R; a=a*d.b-b*d.a; b=b*d.b; int N=Nod(); a /= N; b/=N; return *this;
    }
    5.8.3 Функции члены класса inline (подстановки)
    В ООП при разработке классов создается много маленьких функций, это порождает много вызовов, что затратно по времени. В С++ преодолеть эту трудность помогают функции - подстановки (inline).
    Такие функции можно определить в классе, а можно объявить в классе как обычную функцию – член, а реализовать вне класса как функцию inline.

    Тела функций встраиваются в код на месте вызова этой функции при выполнении препроцессорной обработки.
    Пример определения и объявления inline функции – члена class
    Droby
    { private: int a,b; int
    Nod();
    public:
    Droby(
    int a1, int b1);
    Droby(){a=0;b=1;} void
    Add(Droby &d);
    inline void set_a(
    int a1){a=a1;} //подстановка в классе void set_b(
    int b1); //подстановка, реализация вне класса int get_a(){
    return a;} int get_b(){
    return b;}
    Droby& Sub(Droby &d);
    };
    //реализация объявленных методов inline void
    Droby::set_b(
    int b1)
    { b=b1;
    }
    5.8.4 Методы (функции – члены) экземпляра
    Это нестатические функции - члены.
    5.8.4.1 Указатель this
    Этот указатель определен в каждом методе экземпляра класса неявно.
    Например, можно представить, что в каждом методе класса дроби присутствует оператор:
    Droby *const this;
    Он неявно инициализируется объектом, для которого был вызван метод.
    Используется для явного доступа к членам класса в методе.
    Этот указатель нельзя изменять, поскольку он постоянный (*const) и явно описать его тоже нельзя, т.к . this
    - ключевое слово. this используется в функциях – членах, непосредственно работающих с указателями.

    Пример использования указателя this для возврата измененного в методе объекта
    Метод вычитания возвращает объект класса, из которого выполнено вычитание
    Droby& Droby::Sub(Droby &d)
    { a=this->a*d.b-b*d.a; b=b*d.b; int N=Nod(); this->a/=N;
    //можно просто а this->b/=N; return *this;
    //возвращает измененный объект
    }
    Пример использования указателя this для ссылки на переменные объекта когда имена параметров совпадают с именами полей класса
    Droby::Droby(int a, int b)
    { this->a=a; this->b=b;int N=Nod();this->a= this->a/N; this->b= this->b/N;
    }
    Пример - ошибка. Функция возвращает локальный объект
    Droby& Droby::Sub(Droby &d)
    {
    Droby R;
    R.a= a*d.b-b*d.a;
    R.b=b*d.b; int N=R.Nod();
    R.a/=N;
    R.b/=N; return R;
    }
    5.8.4.2 Перегрузка методов
    Методы, которые имеют одинаковые имена, но отличаются списком параметров, называют перегруженными.
    Пример перегрузки методов сложения дробей class
    Droby
    { private: int a,b;
    int
    Nod();
    public:
    Droby(
    int a1, int b1);
    Droby(){a=0;b=1;} void
    Add(Droby &d);//именится вызвавший объект
    //перегрузка метода Add:результат в вызваший объект void
    Add(Droby &d1, Droby &d2);
    inline void set_a(
    int a1){a=a1;} //подстановка в классе void set_b(
    int b1);
    //подстановка, реализация вне класса int get_a(){
    return a;} int get_b(){
    return b;}
    Droby& Sub(Droby &d);
    }; int main(){
    Droby O1(2,3), O2(3,5);
    O1.Add(O2);
    Droby O3;
    O3.(O1,O2);
    }
    Компилятор по списку параметровотличит один метод от другого.
    5.8.4.3 Функции – члены со спецификацией const
    Такая функция-член не может изменять объект, для которого она вызвана.
    Формат определения
    Заголовок функции-члена (параметры)
    1   2   3   4   5   6   7   8   9   ...   15


    написать администратору сайта