Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.02.2013, 22:47   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию Основы C++ для начинающих от 8Observer8

Здравствуйте, дорогие друзья!

Решил написать памятку для тех, кто начал изучать С++ и только делает первые шаги.

Объектно-ориентированное программирование (ООП)

Объектно-ориентированное программирование (ООП) "стоит на трёх китах":

- Классификация

- Специализация

- Полиморфизм

Классификация - обеспечивается инкапсуляцией и сокрытием данных.

Инкапсуляция - механизм языка, который позволяем создавать модели объектов (классы).

Сокрытие данных (свойств) и внутренних функций (методов) - реализуется с помощью областей private и protected.

Пример классификации. Как известно, живые существа классифицируются на животных, птиц, насекомых и т.д. Для примера, рассмотрим класс животных. У животных очень много свойств (данных). Возьмём свойство "количество глаз". У всех животных два глаза. Создадим переменную, которая будет хранить это значение и метод, который позволит узнать количество глаз животного. Значение переменной "количество глаз" можно узнать только с помощью метода getAmountOfEye(), так как эта переменная закрытая для внешнего мира.

Код:
#include "Animal.h"
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    Animal a;
    cout << "Amount Of Eye = " << a.getAmountOfEye() << endl;

    return 0;
}
Output:
Цитата:
Amount Of Eye = 2
Animal.h
Код:
#ifndef ANIMAL_H
#define	ANIMAL_H

class Animal {
public:
    Animal();
    int getAmountOfEye();
private:
    int amountOfEye;
};

#endif	/* ANIMAL_H */
Animal.cpp
Код:
#include "Animal.h"

Animal::Animal() {
    amountOfEye = 2;
}

int Animal::getAmountOfEye() {
    return amountOfEye;
}
Специализация - возможность продолжения классификации. Реализуется путём наследования.

Создадим на основе класса животных классы собак и кошек. Мы наследуем свойства и методы класса животных (свойство - количество глаз; метод - возможность узнать количество глаз). И добавим к новым подклассам (собак и кошек) новый метод - возможность разговаривать на своём специализированном языке.

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

Путём наследования, получаем два новых класса: класс "Собака" и класс "Кошека", которых объединяет общее свойство - "количество глаз" и метод - "возможность узнать количество глаз".

main.cpp
Код:
#include "Cat.h"
#include "Dog.h"
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    Cat c;
    c.voice();
    
    Dog d;
    d.voice();
    
    cout << "Amount of eyes of a dog = " << d.getAmountOfEye() << endl;

    return 0;
}
Output:
Цитата:
mew-mew
bow-wow
Amount of eyes of a dog = 2
Cat.h
Код:
#include "Animal.h"

#ifndef CAT_H
#define	CAT_H

class Cat : public Animal {
public:
    void voice();
};

#endif	/* CAT_H */
Cat.cpp
Код:
#include "Cat.h"
#include "iostream"
using namespace std;

void Cat::voice() {
    cout << "mew-mew" << endl;
}
Dog.h
Код:
#include "Animal.h"

#ifndef DOG_H
#define	DOG_H

class Dog : public Animal {
public:
    void voice();
};

#endif	/* DOG_H */
Dog.cpp
Код:
#include "Dog.h"
#include <iostream>
using namespace std;

void Dog::voice() {
    cout << "bow-wow" << endl;
}
Примечание 1. Свойства и методы в области private базового класса недоступны в подклассах.

Примечание 2. Если в области protected базового находятся методы или/и свойства, то они будут доступны и в подклассах. Но не будут доступны из вне.
8Observer8 вне форума Ответить с цитированием
Старый 05.02.2013, 22:49   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Полиморфизм - способность объектов по-разному реагировать на одинаковые действия.

Виды полиморфизма:

- статический полиморфизм

- динамический полиморфизм

Статический полиморфизм реализуется с помощью шаблонов классов. Класс создаётся во время компиляции из шаблона (статическое связывание)

Пример. Статический полиморфизм (шаблон класса)

Из шаблона создаются два объекта. Один для работы с целыми числами, а другой для работы c вещественными.

main.cpp
Код:
#include "Comparison.h"
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    Comparison <int> ic;
    int ia = 5;
    int ib = 10;
    cout << "max(" << ia << ", " << ib << ") = " << max(ia, ib) << endl;
    
    cout << endl;
    Comparison <double> dc;
    double da = 5.5;
    double db = 10.5;
    cout << "min(" << da << ", " << db << ") = " << min(da, db) << endl;

    return 0;
}
Output:
Цитата:
max(5, 10) = 10

min(5.5, 10.5) = 5.5
Comparison.h
Код:
#ifndef COMPARISON_H
#define	COMPARISON_H

template <typename T>
class Comparison {
public:
    T max(T a, T b) {
        return (a > b) ? a : b;
    }
    T min(T a, T b) {
        return (a < b) ? a : b;
    }
};

#endif	/* COMPARISON_H */
Динамический полиморфизм реализуется с помощью перезагрузки функций и абстрактного базового класса.

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

Пример. Динамический полиморфизм (перезагрузка методов класса)

main.cpp
Код:
#include <iostream>
#include "Comparison.h"
using namespace std;

int main(int argc, char** argv)
{
    Comparison c;
    int ia = 5;
    int ib = 10;
    cout << "For int:" << endl;
    cout << "max(" << ia << ", " << ib << ") = " << c.max(ia, ib) << endl;
    
    cout << endl;
    double da = 5.5;
    double db = 10.5;
    cout << "For double:" << endl;
    cout << "max(" << da << ", " << db << ") = " << c.max(da, db) << endl;

    return 0;
}
Output
Цитата:
Comparison.h
Код:
#ifndef COMPARISON_H
#define	COMPARISON_H

class Comparison {
public:
    int max(int a, int b);
    double max(double a, double b);
};

#endif	/* COMPARISON_H */
Comparison.cpp
Код:
#include "Comparison.h"

int Comparison::max(int a, int b) {
    return (a > b) ? a : b;
}

double Comparison::max(double a, double b) {
    return (a > b) ? a : b;
}
8Observer8 вне форума Ответить с цитированием
Старый 05.02.2013, 22:50   #3
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Динамический полиморфизм (абстрактный базовый класс) может ещё реализовываться следующем образом. Пусть у нас есть абстрактный базовый класс "Животное". Создадим подклассы класса "Животное": "Кошка", "Собака". Создадим в функции main массив из "животных". Инициализируем массив объектами "Кошка" и "Собака". Теперь объекты класса "Животное" будет по-разному реагировать на вызов метода voice():

Пример. Динамический полиморфизм (абстрактный базовый класс)

main.cpp
Код:
#include "Animal.h"
#include "Dog.h"
#include "Cat.h"
using namespace std;

int main(int argc, char** argv)
{
    Animal *aa[2];

    aa[0] = new Dog;
    aa[1] = new Cat;

    aa[0]->voice();
    aa[1]->voice();

    return 0;
}
Output
Цитата:
bow-wow
mew-mew
Animal.h
Код:
#ifndef ANIMAL_H
#define	ANIMAL_H

class Animal {
public:
    virtual void voice() = 0;
};

#endif	/* ANIMAL_H */
Cat.h
Код:
#include "Animal.h"
#include <iostream>
using namespace std;

#ifndef CAT_H
#define	CAT_H

class Cat : public Animal {
public:
    void voice() {
        cout << "mew-mew" << endl;
    }
};

#endif	/* CAT_H */
Dog.h
Код:
#include "Animal.h"
#include <iostream>
using namespace std;

#ifndef DOG_H
#define	DOG_H

class Dog : public Animal {
public:
    void voice() {
        cout << "bow-wow" << endl;
    }
};

#endif	/* DOG_H */
Полиморфизм объектов реализуется с помощью операторных функций.

Пример. Полиморфизм объектов

В следующем примере реализовано сложение комплексных чисел с помощью переопределённого оператора '+'. Можно переопределить, к примеру, оператор '+' для класса 'Матрица'. Объекты по-разному реагируют на одинаковые действия (для объектов класса 'комплексных чисел' отдельно складываются действительные и мнимые части, а для объектов класса 'матрица' сложение будет реализовано поэлементно).

main.cpp
Код:
#include "Complex.h"
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    Complex a(5.5, 5.5);
    Complex b(10.5, 15.5);
    Complex c;
    
    c = a + b;
    
    cout << c << endl;
    
    return 0;
}
Complex.h
Код:
#include <ostream>
using namespace std;

#ifndef COMPLEX_H
#define	COMPLEX_H

class Complex {
public:
    Complex(double r, double i) : re_(r), im_(i) {
    }

    Complex(double r) : re_(r), im_(0) {
    }

    Complex() : re_(0), im_(0) {
    }
    
    friend Complex operator+(Complex a1, Complex a2);
    
    friend ostream& operator<<(ostream& stream, Complex a);

    double getre() {
        return re_;
    }

    double getim() {
        return im_;
    }

private:
    double re_;
    double im_;
};

Complex operator+(Complex a1, Complex a2) {
    Complex tmp;
    tmp.re_ = a1.re_ + a2.re_;
    tmp.im_ = a1.im_ + a2.im_;
    return tmp;
}

ostream& operator<<(ostream& stream, Complex a) {
    stream << "re = " << a.getre() << endl;
    stream << "im = " << a.getim() << endl;
    return stream;
}

#endif	/* COMPLEX_H */

Последний раз редактировалось 8Observer8; 05.02.2013 в 23:52.
8Observer8 вне форума Ответить с цитированием
Старый 05.02.2013, 23:09   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

А теперь контрольный вопрос.
Есть геометрические фигуры. Есть прямоугольники. Есть квадраты. Есть круги.
Если моделировать всё перечисленное классами, то какие классы должны быть наследниками каких (и каким должно быть наследование)? Какие классы должны быть абстрактными?

Про связь общей концепции полиморфизма с конкретно C++-ной синтаксической фишкой перегрузки операторов я лучше промолчу.
Abstraction вне форума Ответить с цитированием
Старый 05.02.2013, 23:17   #5
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
- Классификация

- Специализация

- Полиморфизм
Ни в одном учебнике или статье не встречал такую классификацию. (судя по тексту статьи "Классификация" и "Специализация" у вас не являются полными синонимами наследования и инкапсуляции)
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 05.02.2013, 23:49   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
Сообщение от ROD Посмотреть сообщение
Ни в одном учебнике или статье не встречал такую классификацию. (судя по тексту статьи "Классификация" и "Специализация" у вас не являются полными синонимами наследования и инкапсуляции)
Механизм инкапсуляции и сокрытия свойств (и методов) позволяет реализовать классификацию.

Механизм наследования позволяет реализовать специализацию.

Это по материалам книги Крупника "Изучаем С++". В последним параграфе своей книги Крупник даёт ссылку на статью Ashley M. Aitken "Object Orientation Revealed!" 11 Proc. 10th Australasian Conference on Information Systems. 1999. Он использовал эту статью для написания заключительного раздела, где он подводит итог.

P.S. Книгу Крупника "Изучаем С++" можно скачать здесь http://programmersforum.ru/showpost....&postcount=147

Последний раз редактировалось 8Observer8; 05.02.2013 в 23:56.
8Observer8 вне форума Ответить с цитированием
Старый 05.02.2013, 23:52   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
Ни в одном учебнике или статье не встречал такую классификацию.
С другой стороны как ты морковку не назови, кролики все равно ее любить будут )
Цитата:
Механизм инкапсуляции и сокрытия свойств (и методов) позволяет реализовать классификацию.
Это с каких это пор?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.02.2013, 23:55   #8
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
С другой стороны как ты морковку не назови, кролики все равно ее любить будут )
Просто, насколько я понял текст статьи, тут это все-таки не морковка, хотя определенно корнеплод, который нравится кроликам.
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс

Последний раз редактировалось ROD; 06.02.2013 в 00:01.
ROD вне форума Ответить с цитированием
Старый 06.02.2013, 00:02   #9
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Это с каких это пор?
А что не так? Вполне логично. Классификация невозможна без механизма создания модели объекта (без инкапсуляции). В модели объекта соединяются свойства и поведение. А так же классификация невозможна без сокрытия данных.

Последний раз редактировалось 8Observer8; 06.02.2013 в 00:09.
8Observer8 вне форума Ответить с цитированием
Старый 06.02.2013, 00:07   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
Классификация невозможна без механизма создания модели объекта (без инкапсуляции).
Возможна. Классификация, это всего лишь выделение объекта в определенную группу. Классификация не относится к внутреннему механизму.
Например. integer паскаля и int для .NET входят в одно и то же семейство - целые числа. Но в паскале это атомарная единица а в дотнете это объект.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Инструкция по созданию заготовки для 2D игр (для начинающих) 8Observer8 Gamedev - cоздание игр: Unity, OpenGL, DirectX 31 20.03.2023 02:01
C++ для начинающих a_Alise Помощь студентам 2 27.03.2016 10:00
C++ для начинающих Haruko_ Помощь студентам 0 23.10.2012 21:41
С++ для начинающих Maxim1 Общие вопросы C/C++ 10 31.05.2010 00:22