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

  • 7.1.1.5 Спецификаторы доступа к полям базового класса из

  • 7.1.1.6 Назначение ограничений доступа наследника к членам

  • 7.1.1.7 Конструктор в производном классе

  • 7.1.1.8 Наследование методов класса

  • 7.1.1.9 Использование конструктора в производном классе

  • 7.1.1.10

  • 7.1.1.11

  • 7.1.2 Множественное наследование

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


    Скачать 2.1 Mb.
    НазваниеСоздание сложных программных систем Объектно ориентированная технология
    Дата21.02.2022
    Размер2.1 Mb.
    Формат файлаpdf
    Имя файлаПособие по ООП в С++.pdf
    ТипАнализ
    #369034
    страница7 из 15
    1   2   3   4   5   6   7   8   9   10   ...   15

    7.1.1.4 Пример реализации класса Плоская фигура
    //Базовый класс – Плоская геометрическая фигура class Base
    {
    private: char nameF[20]; protected: static const double pi; public:
    Base(){ strcpy(nameF,"");} void set_name(char *s); char* get_name() ; double S(); //вычисление пощади double P(); //вычисление периметра
    };
    //Модуль реализации
    //реаизация статической переменной класса const double pi=3.14; void Base::set_name(char *s)
    { strcpy(nameF,s);
    } char* Base::get_name()
    { return nameF;
    } double Base::S()
    { return 0;
    } double Base::P()
    { return 0;
    }
    //Производный - Круг class Circle:public Base
    { private: double r; public:
    Circle(){r=0;}
    Circle( double r1)

    {r=r1;}

    Circle(){cout<<”delete object”;} double S(); double P();
    }; double Circle::S()
    { return pi*r*r;
    } double Circle::P()
    { return (2*3.14*r);
    }
    //Производный класс - Квадрат class Rect:public Base
    { private: double a,b; public:
    Rect(){a=b=0;}
    Rect(double a1, double b1){a=a1; b=b1;} double S(); double P();
    }; double Rect::S()
    { return a*b;
    } double Rect::P()
    { return (2*a+2*b);
    }
    7.1.1.5 Спецификаторы доступа к полям базового класса из
    наследника
    Определение базового класса и ограничения доступа к членам класса class Tbase
    {
    private:
    // доступны только членам этого класса
    int A; void fa();
    protected: // доступны в классе и наследникам int B; void fb();
    public: // доступны в классе, наследникам и внешним функциям int c; void fc(0;
    };
    7.1.1.6 Назначение ограничений доступа наследника к членам
    базового класса
    1) Class Имя : public Имя базового класса {} – открытый базовый класс
    Если базовый класс подключен с использованием public,
    тогда:
    К полям, находящимся в базовом классе под защитой:
    private – прямого доступа к членам базового класса нет, только через методы базового класса типа get и set:
    public – доступ есть
    protected – доступ есть
    Пример. Наследование от открытого класса. Доступ к закрытым данным базового класса невозможен – ошибка компиляции. class Tbase
    { private: int a;
    //доступны членам – функциям класса protected: int x; // доступны в классе и наследникам public: int y;
    // доступны в классе, наследникам и внешним функциям
    };
    Члены открытого базового класса в производном классе сохраняют спецификации доступа.
    Class TNasl:public Tbase
    { public: void fa()
    { cout<//не доступен наследникам ошибка компиляции
    }
    void fx()
    { cout<// доступен наследникам
    } void fy()
    { cout<// доступен наследникам и внешним функциям
    }
    }; int main(
    int argc, _TCHAR* argv[])
    {
    TNasl N1(1,2,3,4);
    N1.fa();
    N1.fx();
    N1.fy(); return 0;
    }
    Результат компиляции
    2) class Имя : private Имя базового класса {} – закрытый базовый класс
    К полям, находящимся базом классе под защитой:
    private – прямого доступа к членам базового класса нет, только через методы базового класса типа get и set;
    public – доступа нет, только через методы базового класса типа get
    и set;
    protected – доступа нет, только через методы базового класса типа
    get и set.
    Пример. Наследование на основе закрытого базового класса class
    Tbase
    { private: int a;
    //доступны членам – функциям класса protected: int x;
    // доступны в классе и наследникам public:
    int y;
    // доступны в классе, наследникам и внешним функциям
    Tbase(
    int a1, int b1, int c1){a=a1;x=b1;y=c1;} int get_a(); int get_x(); int get_y();
    }; int
    Tbase::get_a()
    { return a;
    }; int
    Tbase::get_x(){ return x;
    }; int
    Tbase::get_y(){ return y;
    };
    };
    //Доступ ко всем членам закрытого класса закрыт class
    TNasl:
    private
    Tbase
    { private: int d; public:
    TNasl(
    int a1, int b1, int c1, int d1):Tbase(a1,b1,c1)
    {d=d1;
    } void fa()
    { cout<//не доступен наслединкам - ошибка компиляции
    } void fx()
    { cout<// ,будет доступен наследникам через метод
    } void fy()
    { cout<// не доступен наследникам
    }

    }; int main(
    int argc, _TCHAR* argv[])
    {
    TNasl N1(1,2,3,4);
    N1.fa();
    N1.fx(); return 0;
    }
    Результат компиляции
    3) class Имя : protected Имя базового класса {} – защищенный базовый класс
    К полям, находящимся базом классе под защитой:
    private – остаются private (доступа к членам базового класса нет, только через методы базового класса типа get и set)
    public – становятся защищенными (protected)
    protected – остаются защищенными class Tbase
    { protected: int x; // доступны в классе и наследникам public: int y;//доступны в классе, наследникам и внешним функциям private: int z;
    };
    Class TNasl : protected Tbase
    { public: void f();
    //имеет доступ к полям x y базового класса, но
    //не имеет доступа к полю z.
    }
    Примеры определения ограничения доступа к отдельным членам класса
    1. Закрыть всечлены базового класса для доступа в производном классе class A
    {
    public: int x;
    A(){ std::cout<<"Конструктор А";
    } void Display() { std::cout<<"x="< }
    }; class B: private A{ public:
    B():A(){ std::cout<<"Конструктор B";}
    }; int main()
    {
    A O1;
    O1.Display();
    // доступная функция
    B O2;
    O2.Display();
    // не доступная функция,
    //так как закрытый базовый класс return 0;}
    2. Открыть выборочно члены базового класса class
    B: private
    A
    { public
    :
    B():A(){std::cout<<
    "Constructor B"
    ;}
    A::Display;
    // элемент имени А:: означает, что член базового класса должен остаться открытым
    }; main()
    {
    A O1;
    O1.Display();
    // доступная функция
    B O2;
    O2.Display();// доступная функция, так как она сделана открытой
    // в закрытом базовом классе
    }
    7.1.1.7 Конструктор в производном классе
    Конструктор НЕ наследуется, поэтому если базовый класс имеет конструктор, то наследник должен иметь конструктор.

    Конструктор производного класса вызывает конструктор базового класса, чтобы инициализировать поля базового класса.
    Нельзя явно вызвать конструктор базового класса из конструктора наследника.
    Пример класса Геометрическая фигура, с двумя наследниками: Круг и
    Прямоугольник
    #include
    "stdafx.h"
    #include
    "string.h"
    #include
    using namespace std; class
    Base
    { private: char nameF[20]; public:
    Base();
    Base(
    char
    *s); void set_name(
    char
    *s); char
    * get_name() ; virtual double S();
    //вычисление пощади virtual double P();
    //вычисление периметра
    };
    Base::Base(){ strcpy_s(nameF,
    ""
    );}
    Base:: Base(
    char
    *s){ strcpy_s(nameF,s);} void
    Base::set_name(
    char
    *s)
    { strcpy_s(nameF,s);
    } char
    * Base::get_name()
    { return nameF;
    } double
    Base::S()
    { return 0;
    } double
    Base::P()
    {
    return
    0;
    }
    //Наследник - Круг class
    Circle:
    public
    Base
    { private: double r; public:
    Circle(){r=0;}
    Circle( double r1, char
    *s):Base(s){//неявный вызов конструктора r=r1;
    }
    Circle(){ cout<<"delete object";
    } double
    S(); double
    P();
    };
    //Реализация методов double
    Circle::S()
    { return
    3.14*r*r;
    } double
    Circle::P()
    { return
    (2*3.14*r);
    }
    //Производный класс - Прямоугольник class
    Rect:
    public
    Base
    { private: double a,b; public:
    Rect():Base(){a=b=0;}
    Rect(
    double a1, double b1,
    char
    *s):Base(s){a=a1; b=b1;} double
    S(); double
    P();

    }; double
    Rect::S()
    { return a*b;
    } double
    Rect::P()
    { return
    (2*a+2*b);
    } int
    _tmain(
    int argc, _TCHAR* argv[])
    {
    Base B; cout<<
    "P="
    <' '
    <<
    "S="
    <"Base"
    ;
    Circle C(3,s);
    B=C; strcpy_s(s,
    "Circle"
    ); cout<<
    "P="
    <' '
    <<
    "S="
    <Base *PB=&C; cout<<
    "P="
    <
    P()<<
    ' '
    <<
    "S="
    <
    S()<Base *Masobject[5]; for
    (
    int i=0;i<5;i++)
    Masobject[i]=
    new
    Base; strcpy_s(s,
    "Base"
    );
    Masobject[0]=&Base(s); strcpy_s(s,
    "Circle"
    );
    Masobject[1]=&Circle(5,s);
    Masobject[2]=&Circle(8,s); strcpy_s(s,
    "Rect"
    );
    Masobject[3]=&Rect(2,3,s);
    Masobject[3]=&Rect(2,3,s); cout<get_name()<S()<get_name()<S()<}

    7.1.1.8 Наследование методов класса
    Наследуются члены базового класса с соответствующими ограничениями: методы и поля данных, они могут использоваться функциями производного класса, если они находятся под защитой public и protected и пользоваться частичными ограничениями (см.7.1.1.6).
    В производном классе могут быть свои члены – данные и методы.
    Не наследуются:

    Конструктор

    Дружественные функции (они не являются членами класса)

    Оператор присваивания (объекту производного класса нельзя
    присваивать объекты базового класса).
    Пример доступ из производного класса к закрытым членам базового класса и вызов конструктора базового класса сlass Tbase
    { private: int count; public:
    TBase(){ count=0;} void SetCount(int c) { count=c;}; int GetCount() {return count;};
    }; сlass TNasl2:public TBase
    { private: int secondCount; public:
    TNasl2(); void changecount(int n);// метод наследника
    }
    TNasl2:: TNasl2():TBase(){
    //заголовок конструктора
    //вызов базового класса secondCount=0;
    }
    // ошибка доступа к полю void TNasl2:: changecount()
    { count+=1;
    }
    // нет ошибки доступа к полю
    void TNasl2:: changecount(int n)
    {
    SetCount(GetCount()+n);
    }
    7.1.1.9 Использование конструктора в производном классе
    Пример
    #include

    #include
    "string.h" class
    TBase
    { private
    : char
    *basep; public
    :
    TBase(
    const char
    *s){ basep=strdup(s);}
    //копирование s
    TBase( ){
    delete basep;}
    //освобождает ДП const char
    *GetStr(){
    return basep;}
    };
    //Создадим наследника и посмотрим, что происходит в производном классе class
    TNasl:
    public
    TBase
    { private
    : char
    *uppercasep; public
    :
    TNasl(
    const char
    *s);
    TNasl(){
    delete uppercasep;} const char
    *GetStr(){
    return uppercasep;}
    };
    //Конструктор можно реализовать следующим образом
    TNasl::TNasl(
    const char
    *s):TBase(s) { uppercasep =strdup(s);
    //конвертируем первую букву в прописную uppercasep[0]=toupper(uppercasep[0]);
    } int main()
    {
    TBase O1(
    "hello"
    );
    TNasl O2(
    "hello"
    ); std::cout< 0;
    }

    7.1.1.10
    Деструктор в производном классе
    Деструктор требуется определить в классе, в котором определены динамически создаваемые поля данных. Деструктор должен освободить динамическую память.
    Деструктор разрушает любой объект при выходе объекта из области видимости. Деструктор не определен в классе, но всегда вызовется при выходе объекта из области видимости.
    Если конструктор производного класса должен вызывать конструктор базового класса при создании объекта производного класса, то деструктору эти строгости не нужны.
    Пример класса имеющего деструктор, который будет вызван при завершении программы автоматически using namespace std; class
    TBase
    { private: char
    *bpase; public:
    TBase(
    const char
    *s) {bpase=_strdup(s);}
    TBase(){
    delete bpase;} const char
    *GetStr(){
    return bpase;}
    }; class
    TNasl : public
    TBase
    { private: char
    *upperbcasep; public:
    TNasl(
    const char
    *s);
    TNasl(){
    delete upperbcasep;} const char
    *GetUStr(){
    return upperbcasep;}
    };
    TNasl::TNasl(
    const char
    *s):TBase(s)
    { upperbcasep=_strupr(_strdup(s));
    } int main(
    int argc, _TCHAR* argv[])
    {
    //TBase O1("hello");
    TNasl O2(
    "hello"
    );
    cout<//вывод hello cout<//вывод HELLO system(
    "PAUSE"
    ); return 0;
    }
    Примечание. Конструктор наследника вызовет конструктор базового класса, который создаст поле bpase и запишет в него слово hello. Затем конструктор создаст свое поле upperbcasep и запишет в него тоже слово, только прописными буквами.
    Пример общедоступного наследования (public) class
    TDate
    { protected: int d, m, y; public:
    TDate(
    int d1, int m1, int y1){d=d1;m=m1;y=y1;} void out() {cout<'.'
    <'.'
    <}; class
    TNaslD: public
    TDate
    { protected: static const char mm=
    'A'
    ; public:
    TNaslD(
    int d1, int m1, int y1):TDate(d1, m1, y1){}; void out() {cout<' '
    <<
    char
    (mm)<<
    ' '
    <}; int main(
    int argc, _TCHAR* argv[])
    {
    TDate O1(12, 4, 2015);
    O1.out();
    TNaslD O2(12,4,2015);
    O2.out(); system(
    "PAUSE"
    ); return 0;
    }

    7.1.1.11
    Алгоритм выполнения конструктора и деструктора при
    создании и уничтожении производных классов
    Деструктор - метод, уничтожающий объект класса, после выхода объекта из области видимости.
    Если конструктор наследника должен вызвать конструктор базового класса, то деструктор не нуждается в таких строгостях.
    В производном классе явный деструктор нужен только при наличии членов, которые нужно удалять (динамические переменные), когда объект производного класса выходит из области видимости.
    7.1.2 Множественное наследование
    Пример реализации множественного наследования
    Класс вещественного числа, из целой и дробной части. Целая часть числа и дробная часть – это классы, а вещественное число - производный класс.
    #include
    class integerPartOfNumber{ protected
    : int x; public
    : integerPartOfNumber(
    int x1){x=x1;}
    }; class floatPartOfNumber{ protected
    : int y; public
    : floatPartOfNumber(
    int y1){y=y1;}
    }; class floatNumber:
    public floatPartOfNumber,integerPartOfNumber{ protected
    : double z; public
    : double f(
    int m){ int a=m%10; if
    (m){ return f(m/10);
    } z=z*1/10+a; return z;
    }
    floatNumber(
    int x1,
    int y1):integerPartOfNumber(x1),floatPartOfNumber(y1)
    { z=0; int p=1; while
    (y>p){ p=p*10;
    } while
    (y){ z=z+y%10*1.0/p; y=y/10; p=p/10;
    } z=x+z;
    } double getNumber(){
    return z;}
    }; int
    _tmain(
    int argc, _TCHAR* argv[])
    { floatNumber O(2,345); std::cout< 0;
    }
    7.2
    Ассоциация
    Создадим модель системы «Управление выдачей и возвратом книг».
    Основными классами является:
    Reader (читатель), со свойствами: numreader(номе читательского билета), FIO.
    +setnumreader() : void
    +getnumreaer() : int
    +setFIO() : void
    +getFIO() : string
    +Reader()
    -numreader : int
    -FIO : string
    Reader
    Book (книга) со свойствами: name, author,invnumer
    (инвентарный номер – уникальный номер каждой книги библиотеки)
    +setname() : void
    +setauthor() : void
    +setinvnum() : void
    +Book()
    +getname() : string
    +getauthor() : string
    +getinvnum() : int
    -name : string
    -author : string
    -invnumer : int
    Book

    Ассоциация показывает отношения между объектами-экземплярами класса.
    7.2.1 Бинарная ассоциация
    В модель добавим класс «RecordBook» - запись о книге взятой читателем. Книга может быть включена только в одну запись, мощность связи
    1 к 1. На модели Включена в запись – название ассоциации. Свойство invnumer в кассе
    RecordBook представляет связь с классом
    Book.
    +setname() : void
    +setauthor() : void
    +setinvnum() : void
    +Book()
    +getname() : string
    +getauthor() : string
    +getinvnum() : int
    -name : string
    -author : string
    -invnumer : int
    Book
    +setinvnumer() : void
    +setdatain() : void
    +setdataout() : void
    +getinvnumer() : int
    +getdatain() : string
    +getdataout() : string
    -invnumer : int
    -datain : string
    -dataout : string
    RecordBook
    -Вкючена в запись
    1 1
    Реализация классов class
    Book{ private
    : string name; string author; int invnumer; public
    :
    Book(string name1,string author1, int invn){ name=name1; author=author1; invnumer=invn;
    } void setname(string sname){ name=sname;
    } void setauthor(string sauthor){ author=sauthor;
    } void setinvnumer(
    int num){ invnumer=num;
    } string getname(){ return name;
    } string getauthor(){ return name;
    } string getinvnum(){ return name;
    }
    }; class
    RecordBook{ private
    : int invnumer; string datain; string dataout; public
    : void setdatain(string din){ datain=din;

    } void setdataout(string dout){ dataout=dout;
    } void setinvnumer(
    int num){ invnumer=num;
    } string getdatain(){ return datain;
    } string getdataout(){ return dataout;
    } int getinvnumer(){ return invnumer;
    }
    };
    //выбрать книгу из списка int createRecordBook(vector list){ int inv; for
    (
    int i=0;i{ std::cout<' '
    <' '
    <'
    '
    <} std::cout<<
    "Viberite nomer book"
    ; std::cin>>inv; return inv;
    } int main()
    { vector listBook; listBook.push_back(Book(
    "AAA"
    ,
    "Ab"
    ,111)); listBook.push_back(Book(
    "BBB"
    ,
    "Bb"
    ,122)); listBook.push_back(Book(
    "CCC"
    ,
    "Cb"
    ,133));
    RecordBook R; string d1=
    "10.01.2019"
    , d2=
    "17.02.2019"
    ;
    R.setinvnumer(vector list));
    R.setdatain(d1);
    R.setdataout(d2); return
    0;
    }
    7.3
    1   2   3   4   5   6   7   8   9   10   ...   15


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