Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Andrey040601
 Аватар для Andrey040601
2 / 2 / 3
Регистрация: 13.07.2014
Сообщений: 127
Завершенные тесты: 5
#1

В чем смысл полиморфизма - C++

19.07.2015, 22:57. Просмотров 500. Ответов 17
Метки нет (Все метки)

Объясните, пожалуйста, смысл полиморфизма. Не могу никак вникнуть. Где и как он используется? И примерчик, пожалуйста
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2302 / 1018 / 232
Регистрация: 30.11.2013
Сообщений: 3,374
19.07.2015, 23:56     В чем смысл полиморфизма #2
прочитайте книги, статьи.
Andrey040601
 Аватар для Andrey040601
2 / 2 / 3
Регистрация: 13.07.2014
Сообщений: 127
Завершенные тесты: 5
20.07.2015, 00:00  [ТС]     В чем смысл полиморфизма #3
rikimaru2013, читал. Вроде как понял, но вот примера нормального не нашел. По этому так и не понял, зачем полиморфизм нужен
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2302 / 1018 / 232
Регистрация: 30.11.2013
Сообщений: 3,374
20.07.2015, 00:19     В чем смысл полиморфизма #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <vector>
using namespace std;
class Figure
{
public:
    virtual float getSquare() = 0;
};
 
class Rectangle :
    public Figure
{
public:
    virtual float getSquare()
    {
        return 1; // тут будет крутая формула a * b
    }
};
class Triangle :
    public Figure
{
public:
    virtual float getSquare()
    {
        return 2; // тут будет крутая формула 1.0 / 2.0 * a  * h
    }
};
class Circle :
    public Figure
{
public:
    virtual float getSquare()
    {
        return 3; // тут будет крутая формула 3.14 * r * r
    }
};
 
int main()
{
    vector<Figure*> arr;
    arr.push_back(new Rectangle());
    arr.push_back(new Circle());
    arr.push_back(new Triangle());
    arr.push_back(new Triangle());
    arr.push_back(new Rectangle());
 
 
 
    for(int i = 0; i < arr.size(); i++)
    {
        cout << arr[i]->getSquare() << endl;
    }
}
Добавлено через 2 минуты
В более крутых проектах:
есть понятие в игре юнит - у него виртуальный метод moveTo(); Кто-то идёт пешком, какая-то гарпия летает, кто-то телепортируется по местности, но у всех есть метод moveTo(), который они переопределили для себя. И если появится еще 1 вид передвижения, это не беда, унаследуем, переопределим и будет он ... к примеру, нырять под землю и в нужной точке выныривать.
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,149
Завершенные тесты: 1
20.07.2015, 09:53     В чем смысл полиморфизма #5
Цитата Сообщение от Andrey040601 Посмотреть сообщение
Объясните, пожалуйста, смысл полиморфизма. Не могу никак вникнуть. Где и как он используется? И примерчик, пожалуйста
есть собака, и кошка.
и то, и другое - животные.
собака лает. кошка мяукает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
IAnimal
{
    // не забываем про виртуальный диструктор
    virtual ~IAnimal(){}
 
    // все животные умеют издавать звуки
    virtual void sound() = 0;
};
 
struct Dog: IAnimal
{
    virtual void sound() { cout <<"гаф-гаф\n"; }
}
 
struct Cat: IAnimal
{
    virtual void sound() { cout <<"мяу-мяу\n"; }
}
 
// функция не знает с каким именно животным она работает
void sound(IAnimal& animal)
{
 
    // но это не мешает ей воспроизвести звучание любого животного
    // которого ей прислали
 
   // гафкай, или мяукай, в зависимости от того, кто ты там
   animal.sound();
}
рассмотрим класс IAnimal
такие классы любят называть "интерфейсы".
он задает методы управления всеми возможными животными.
в данном случае он сообщает: каким бы ни было животное,
но у него обязательно будет метод sound,
который заставит животное издавать звуки.

и есть кучка наследников: кошки, собаки.
это - разные классы.
у них разное поведение.
в данном случае они по разному звучат.

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

поэтому, даже не зная точно, кто это:
кошка, или собака, мы можем заставить их звучать.

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



зачем это нужно?

вот другой пример:

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

поскольку над проектом будет работать несколько программистов,
то нужно так распределить наши роли,
что бы мы друг другу не мешались.

допустим, вы будете писать код юнитов.
а я - код вооружения.

но как вы сможете писать код юнита, если вооружения ещё никакого нет?
как вы научите своих солдатиков стрелять из оружения, если код оружия ещё не написан?

и вот, мы с вами договариваемя: у любого вида оружия есть интерфейс IWeapon,
у которого есть метод Fire.

что бы юнит сделал выстрел, он должен вызвать этот метод для объект "оружия".
и уже не важно что это за оружие, но если у него есть такой метод,
ваш юнит сможет сделать выстрел.


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

и становится возможным налету (в момент выполнения программы) заменить одно оружие на другое.

солдатик достает пистолет и делает: "пиф-паф!"
а потом достает базуку и делает: "бууумс!"

при этом солдатик не знает как на самом деле устроен объект,
из которого он стреляет.

ему просто пофигу,
он сможет стрелять из любого оружия,
лишь бы у него был спуской крючок: IWeapon::Fire

это делает возможным:
1. командную разработку программного обеспечения, так, что бы никто никому не мешался.
и никого не ждал.

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

3. расширяемость
(что бы добавить ещё одну пушку - достаточно просто унаследоваться от интерфейса,
и реализовать определенные методы,
и все солдатики априори уже смогут пользоваться новым оружием без изменений в своем коде.).
Andrey040601
 Аватар для Andrey040601
2 / 2 / 3
Регистрация: 13.07.2014
Сообщений: 127
Завершенные тесты: 5
20.07.2015, 10:13  [ТС]     В чем смысл полиморфизма #6
Спасибо большое!

Но вот я так и не понял этого:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class First
{
public:
    virtual void AnyFunc()
    {
        cout << "First" << endl;
    }
};
 
class Second : public First
{
public:
    virtual void AnyFunc()
    {
        cout << "Second" << endl;
    }
};
 
int main()
{
    First *obj_1 = new Second;
    First *obj_2 = new First;
 
    obj_1->AnyFunc();
    obj_2->AnyFunc();
 
    _getch();
}
В чем смысл
C++
1
 First *obj_1 = new Second;
? Чем оно отличается от
C++
1
 Second *obj_1 = new Second;
?
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 10:20     В чем смысл полиморфизма #7
Смысл полиморфизма в том, что вы вместо базового класса можете использовать наследника. Например (тут рядом моя тема есть) мне нужно выводить информацию из объекта. я передаю ему ссылку (или указатель) на ostream. если пользователь выбирает пункт меню "вывод в файл" для вывода передаётся объект ofstream, если же пользователь выбрал "вывод в консоль", то передаётся cout.
zss
Модератор
Эксперт С++
 Аватар для zss
6111 / 5714 / 1849
Регистрация: 18.12.2011
Сообщений: 14,593
Завершенные тесты: 1
20.07.2015, 10:23     В чем смысл полиморфизма #8
Обратите внимание на то, что в первом случае указателю на БАЗОВЫЙ класс присваивается адрес ПРОИЗВОДНОГО класса.
В этом случае obj_1->AnyFunc(); вызывает виртуальный метод ПРОИЗВОДНОГО класса, т.е. того класса, адрес которого был присвоен.

Соответственно, если присвоен адрес базового класса, то obj_2->AnyFunc(); вызывается метод базового класса.

Second *obj_1 = new Second;obj_1->AnyFunc(); - естественно, вызовется метод производного класса.

А для вызова метода базового класса придется написать
C++
1
obj_1->First::AnyFunc();
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 10:28     В чем смысл полиморфизма #9
вот код для моего примера:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <fstream>
 
using namespace std;
 
void print(ostream* os){
    (*os)<<"hi!";
}
 
int main(){
 
    int c;
 
    cout<<"1 - to console, 2 - to file"<<endl;
 
    cin>>c;
 
    switch (c)
    {
    case 1:
        print(&cout);
        break;
    case 2:
 
        ofstream os;
        os.open("out.txt");
        print(&os);
        os.close();
 
        break;
    }
 
    return 0;
}
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,149
Завершенные тесты: 1
20.07.2015, 10:29     В чем смысл полиморфизма #10
Цитата Сообщение от Andrey040601 Посмотреть сообщение
В чем смысл
объясняю на примере:

напишите пожалуйста функцию,
которая сможет принимать любые объекты :
First/Second , может быть в будущем ещё наследника добавим.

то есть функция обязана априори принять любого члена иерархии классов.
и дернуть ему функцию AnyFunc.

как вы это сделаете?

-----------------------------------------------------------------------------------
вот у вас есть кошка и собака, а может быть ещё и волк, или лиса.
не важно. у них у всех есть метод "звучать".

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

что бы вам не пришлось писать по функции на каждый конкретный тип животного.

я хочу, что бы вы написали только одну.
но эта одна сможет заставить звучать любого животного, которого её пришлют.
zss
Модератор
Эксперт С++
 Аватар для zss
6111 / 5714 / 1849
Регистрация: 18.12.2011
Сообщений: 14,593
Завершенные тесты: 1
20.07.2015, 10:51     В чем смысл полиморфизма #11
VVildVVolf, разъясните подробно, какое отношение имеет Ваш код к теме "Полиморфизм".
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 10:59     В чем смысл полиморфизма #12
функция print принимает указатель на ostream, при этом в функции main эта функция вызывается с передачей аргументов разных типов.

п.с. честно признаюсь, в нюансы именно стримов не вникал досконально, что откуда наследуется и к чему приводится, но использование полиморфизма ВЫГЛЯДИТ примерно так.
zss
Модератор
Эксперт С++
 Аватар для zss
6111 / 5714 / 1849
Регистрация: 18.12.2011
Сообщений: 14,593
Завершенные тесты: 1
20.07.2015, 11:56     В чем смысл полиморфизма #13
Оператор << не является методом класса ostream.
это глобальный перегруженный оператор.
Поэтому в
Цитата Сообщение от VVildVVolf Посмотреть сообщение
(*os)<<"hi!";
никакого полиморфизма нет.
Кроме того, даже если бы и был, то операция разыменования *os приводит к тому,
что этот метод вызывался бы как обычный, а не как виртуальный.
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 12:01     В чем смысл полиморфизма #14
Цитата Сообщение от zss Посмотреть сообщение
Кроме того, даже если бы и был,
даже если бы и был - это к полиморфизму или к
Цитата Сообщение от zss Посмотреть сообщение
не является методом класса ostream.
?
суть здесь не в перегрузке оператора <<, а в том, что передаются экземпляры разных классов, что влияет на итоговое поведение соответственно. или же в обоих случаях передаются экземпляры одного и того же класса?Оо
zss
Модератор
Эксперт С++
 Аватар для zss
6111 / 5714 / 1849
Регистрация: 18.12.2011
Сообщений: 14,593
Завершенные тесты: 1
20.07.2015, 12:11     В чем смысл полиморфизма #15
VVildVVolf, Вы продемонстрировали не полиморфизм, а родственность производных классов.
Т.е. то, что указателю на базовый класс можно присваивать адрес производного класса без каких-либо преобразований.
SmittWesson
 Аватар для SmittWesson
120 / 169 / 17
Регистрация: 04.06.2014
Сообщений: 1,273
20.07.2015, 12:13     В чем смысл полиморфизма #16
Цитата Сообщение от Andrey040601 Посмотреть сообщение
Объясните, пожалуйста, смысл полиморфизма. Не могу никак вникнуть. Где и как он используется? И примерчик, пожалуйста
Ну, на бытовом уровне, смысл полморфизма, когда друзья Вам дают кличку. Вы, уже называетесь в их среде по-другому, но Ваша суть от этого не изменилась-ведь? Вот, в принципе, и всё .
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,149
Завершенные тесты: 1
20.07.2015, 12:18     В чем смысл полиморфизма #17
Цитата Сообщение от zss Посмотреть сообщение
никакого полиморфизма нет.
есть. статический.

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

но в данном случае он был реализован за счет приведения по иерархии наследования.
это работает, потому что сам по себе std::ostream не более, чем обертка,
которая делегирует задачу своему очень даже полиморфному внутреннему механизму буфера вывода.

http://www.cplusplus.com/reference/ios/ios/rdbuf/

Цитата Сообщение от zss Посмотреть сообщение
операция разыменования *os приводит к тому,
что этот метод вызывался бы как обычный, а не как виртуальный.
ничего подобного.

C++
1
2
3
4
5
IAnimal& reference = getAnimal();
 
reference.virtualMethod(); // <--- для ссылок динамический полиморфизм 
// работает точно так же
// как и для обычных указателей.
Добавлено через 2 минуты
Цитата Сообщение от zss Посмотреть сообщение
Вы продемонстрировали не полиморфизм, а родственность производных классов.
он продемонстрировал два принципиально разных поведения
(вывод в консоль, или вывод в файл),
осуществляемых через единый интерфейс для объектов разных типов.

это и есть красноречивый пример полиморфизма.


"родственность производных классов" - это конечно круто звучит.
учитывая, что так можно обозвать
любое проявление динамического полиморфизма,
осуществляемого посредством виртуальных функций-членов.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.07.2015, 17:31     В чем смысл полиморфизма
Еще ссылки по теме:

В чем смысл выражения "y+='A'-10" ? C++
В чем смысл косой черты в #include C++
Виды полиморфизма C++ C++
C++ В чем смысл двух перегрузок одного оператора?
Смысл использования полиморфизма C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Andrey040601
 Аватар для Andrey040601
2 / 2 / 3
Регистрация: 13.07.2014
Сообщений: 127
Завершенные тесты: 5
23.07.2015, 17:31  [ТС]     В чем смысл полиморфизма #18
Большое всем спасибо!
Yandex
Объявления
23.07.2015, 17:31     В чем смысл полиморфизма
Ответ Создать тему
Опции темы

Текущее время: 00:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru