Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Dobbyman
0 / 0 / 0
Регистрация: 26.05.2016
Сообщений: 7
#1

Смысл использования полиморфизма - C++

26.05.2016, 14:03. Просмотров 121. Ответов 5
Метки нет (Все метки)

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
#include <iostream>
 
using namespace std;
 
class A{
 
public:
    virtual void speak() {}
 
};
 
class B: public A{
public:
    void speak() {
        cout << "class a" << endl;
    }
 
};
 
class C: public A{
public:
    void speak() {
        cout << "class b" << endl;
    }
 
};
 
int main() {
 
    B lo;
    C na;
 
    A *en1 = &lo;
    A *en2 = &na;
 
    en1->speak();
    en2->speak();
 
    return 0;
}
Я не могу никак понять, для чего он нужен. Это - пример полиморфизма через виртуальные функции.
Мы создаем объекты lo и na, после создаем указатели на класса A и присваем им адреса наших предыдущих объектов, в результате, благодаря нашему виртуальному методу speak(), уникальные реализации классов-наследников доступны через базовый класс.
Это все замечательно, но почему? Каждый раз, чтобы это сделать, нужно создавать en1,en2 , хотя т.к. уже есть наследование, то методы доступны и через lo и na. Да, мы реализовали доступ через базовый класс. Но зачем?
Спасибо.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.05.2016, 14:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Смысл использования полиморфизма (C++):

В чем смысл полиморфизма - C++
Объясните, пожалуйста, смысл полиморфизма. Не могу никак вникнуть. Где и как он используется? И примерчик, пожалуйста

Пример использования генератора случайных чисел для демонстрации динамического полиморфизма - C++
Пример использования генератора случайных чисел для демонстрации динамического полиморфизма.Я в шоке не могу не где найти может тут кто...

В чём смысл использования указателей на функции - C++
Собсно,я не могу понять,в чём смысл использования указателей на функции,ведь можно вызывать функции напрямую.Или же это сделано чисто для...

Использование полиморфизма - C++
Помогите написать программу, которая использует перегрузительную функцию для работы с данными типов long и double и определяет...

Виды полиморфизма C++ - C++
Разбираю полиморфизм. Наткнулся на классификацию с тремя видами:1.специальный, 2.параметрический и 3.подтипов(включения). Все ли...

иллюстрация полиморфизма - C++
Доброго времени суток!написал примитив для иллюстрации полиморфизма,ориентировался по видеокурсам с ТыТрубы #include&lt;iostream.h&gt; ...

5
zss
Модератор
Эксперт С++
6530 / 6092 / 2007
Регистрация: 18.12.2011
Сообщений: 15,843
Завершенные тесты: 1
26.05.2016, 14:33 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Dobbyman Посмотреть сообщение
Я не могу никак понять, для чего он нужен
Обратите внимание
Цитата Сообщение от Dobbyman Посмотреть сообщение
C++
1
2
en1->speak(); 
en2->speak();
Оба указателя - это указатели на базовый класс A.
Однако, в первом случае вызывается метод класса B,
а во втором - метод класса A.

Как раз в этом и есть смысл.
Мы заранее не знаем, как метод будет реализован в производном классе,
Но можем написать код, который вызовет этот метод.
1
nimazzzy
Заблокирован
26.05.2016, 14:36 #3
Помогает расширяемости. Программа, которая использует указатель на A и вызывает speak() не нуждается в перекомпиляции существующего кода, и сорцы существующих классов не нуждаются в изменении для добавления нового функционала в метод speak. Таким образом снижаются риски при программировании. Ты расширяешь функционал приложения, не меняя существующий код. Если грубо и вкратце.
Конечно, если ты свои классы, как путный программист, отправишь в отдельные модули, а не все в одном, как сейчас.
1
AlexVRud
459 / 170 / 44
Регистрация: 04.07.2014
Сообщений: 475
26.05.2016, 15:26 #4
Dobbyman, Плохой пример выбрал.

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
#include <iostream>
#include <string>
#include <vector>
 
class Animal {
public:
  virtual ~Animal() = default;
  virtual std::string talk() = 0;
};
 
class Cat : public Animal {
public:
  virtual ~Cat() = default;
  virtual std::string talk() override
  {
    return "Meow!";
  };
};
 
class Dog : public Animal {
public:
  virtual ~Dog() = default;
  virtual std::string talk() override
  {
    return "Woof!";
  };
};
 
int main()
{
  std::vector<Animal *> animals;
  animals.push_back(new Cat());
  animals.push_back(new Dog());
  animals.push_back(new Cat());
 
  for (size_t i = 0; i < animals.size(); ++i) {
    std::cout << i << ": " << animals[i]->talk() << std::endl;
  }
 
  for (size_t i = 0; i < animals.size(); ++i) {
    delete animals[i];
  }
 
  return 0;
}
Результат:
Код
0: Meow!
1: Woof!
2: Meow!
1
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
26.05.2016, 17:17 #5
Цитата Сообщение от Dobbyman Посмотреть сообщение
Это все замечательно, но почему? Каждый раз, чтобы это сделать, нужно создавать en1,en2 , хотя т.к. уже есть наследование, то методы доступны и через lo и na. Да, мы реализовали доступ через базовый класс. Но зачем?
Ну, чтобы это понять, нужно получше разобраться что такое открытое наследование. А это некоторая специализация базового класса, т.е. описание некоторого подмножества множества объектов базового класса.
Ну, к примеру, базовый класс у нас Станок. И у множества объектов-станков есть подмножество объектов - сверлильных станков. Для описания этого подмножества объявляем класс-наследник Сверлильный_станок. Базовый класс можно специализировать в наследнике просто добавляя новые члены (данные и функции), а можно специализировать поведение базовых функций-членов, это как раз и делается через механизм виртуальных функций.
Ну, допустим, вы отдаете всем объектам-станкам в цеху команду Обработать_деталь. С одной стороны, это базовая функция-член класса Станок, так как все станки должны обрабатывать детали. С другой - каждый станок обрабатывает деталь в соответствии со своей специализацией, - сверлильный - сверлит, токарный точит, и т.д.
Технически для этого нужно создать коллекцию указателей на базовый класс Станок, и поместить туда адреса всех объектов-станков. Тогда, чтобы каждый станок начал обрабатывать деталь, нужно всем станкам дать команду Обработать_деталь, и каждый выполнит ее в соответствии со своей специализацией.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
26.05.2016, 19:42 #6
Цитата Сообщение от Dobbyman Посмотреть сообщение
хотя т.к. уже есть наследование, то методы доступны и через lo и na.
Если бы и не было наследования они были бы доступны через экземпляры классов A и B, например через lo и na. Дело не в том что они недоступны, а в том как они доступны. Если Вы хотите создать коллекцию родственных сущностей вроде экземпляров A и B можно бы создать класс С в котором есть указатели на A и B и метод который вызывает метод speak того объекта, указатель на который не равен nullPtr. Тогда имея контейнер объектов С можно пройти по нему вызвав метод speak(). Это будет работать если A и B не родственники и единственное что их объеденияет это то, что они умеют void speak(); (это тоже не обязательно с формальной точки зрения).
При использовании полиморфизма итерация с вызовом speak() идёт по контейнеру указателей на базовый класс инициализированных адресами объектов A и B (которые родственники). Это легче.
1
26.05.2016, 19:42
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.05.2016, 19:42
Привет! Вот еще темы с ответами:

Реализация полиморфизма - C++
Читал что существует примерно 10 способов реализации полиморфного контейнера. Видел только один где создается виртуальный класс и у него...

Принципы наследования и полиморфизма - C++
Даны натуральное число n, действительные числа a1 a2,...,an. Если последовательность a1 ,a2 ,...,an упорядочена по неубыванию, то...

Неочевидные грабли полиморфизма с++ - C++
Наткнулся в интернете на любопытный код. Спешу поделиться с сообществом. Просто, что бы кто если не в курсе - узнал, и не попал на эти...

Использование свойств полиморфизма - C++
Нужна помощь. Сгенерируйте абстрактный класс типа фигура, создайте производные от него классы типа пятиугольник, прямоугольник. В классах...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

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