Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 28.03.2019
Сообщений: 9
1

Полиморфизм в C++

16.08.2019, 19:29. Показов 1593. Ответов 11
Метки нет (Все метки)

Предположим, что есть родительский класс Parent с виртуальным методом update с одним целочисленным аргументом. Есть также унаследованный от этого класса класс Child, у которого есть метод с таким же названием, но требующий два целочисленных аргумента, вместо одного.

Создаём указатель на Parent и присваиваем ему адрес объекта Child. При попытке вызвать функцию update с двумя аргументами, компилятор выдает ошибку.

Я понимаю, что причина в том, что это две разные функции, и чтобы использовать этот метод таким образом, надо сделать его прототип таким же, как и прототип update класса Child, но таким образом второй аргумент будет лишним.

Это единственный способ решения этой проблемы или есть ещё решения? Иными словами, можно ли переопределить метод, изменив при этом аргументы?
0

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

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.08.2019, 19:29
Ответы с готовыми решениями:

Полиморфизм
Хай :senor: class MyPrint//производный класс { public: MyPrint() { cout << "Constructor...

Полиморфизм
В одной дешевой книжке про него пишут а в другой дорогой нет и понять я почему то немогу точно как...

Полиморфизм
Я хотел реализовать множество, используя множественное наследование, но когда написал template...

С++ и полиморфизм
Здравствуйте. Ответьте пожалуйста на несколько вопросов: 1. Что такое абстрактная функция...

11
"C with Classes"
1485 / 1287 / 485
Регистрация: 16.08.2014
Сообщений: 5,413
Записей в блоге: 1
16.08.2019, 19:56 2
rjomendrive_, так примерно?:
C++
1
2
3
4
5
6
7
8
struct A
{
    virtual void Function(int i, int = 0) {}
};
struct B: A
{
    virtual void Function(int i, int j) override {}
};
0
Эксперт С++
8401 / 4077 / 891
Регистрация: 15.11.2014
Сообщений: 9,165
17.08.2019, 01:47 3
Цитата Сообщение от rjomendrive_ Посмотреть сообщение
таким образом второй аргумент будет лишним.
Цитата Сообщение от rjomendrive_ Посмотреть сообщение
унаследованный от этого класса класс Child, у которого есть метод с таким же названием, но требующий два целочисленных аргумента, вместо одного.
ты определись: второй аргумент требуется для работы, или он - лишний?

как у тебя вообще так получается:
с одной стороны ты заявляешь, что аргумент лишний,
а с другой - что он нужен?

никакого логического противоречия не наблюдаешь?

и что бы лучше определялось,
выбрось из головы этот абстрактный "ни о чем":
Цитата Сообщение от rjomendrive_ Посмотреть сообщение
Child
Цитата Сообщение от rjomendrive_ Посмотреть сообщение
Parent
у классов должны быть говорящие имена,
которые отражают их предназначение.

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

а покамест, со стороны,
твои Child, Parent - это сферические кони в вакууме.
0
0 / 0 / 0
Регистрация: 28.03.2019
Сообщений: 9
17.08.2019, 07:12  [ТС] 4
hoggy, второй аргумент будет лишним в классе Parent, но будет нужным в классе Child.

Имена Parent и Child выбраны специально, чтобы никому не забивать голову ненужной информацией. Зачем тебе знать, для чего именно предназначены классы, если вопрос совсем другой?
0
506 / 741 / 132
Регистрация: 10.08.2015
Сообщений: 3,485
17.08.2019, 07:20 5
Цитата Сообщение от _stanislav Посмотреть сообщение
struct A
{
* * virtual void Function(int i, int = 0) {}
};
struct B: A
{
* * virtual void Function(int i, int j) override {}
};
че за бред?

покажи код и текст ошибки
0
0 / 0 / 0
Регистрация: 28.03.2019
Сообщений: 9
17.08.2019, 07:26  [ТС] 6
_stanislav, я правильно понимаю, что в таком случае память под второй аргумент функции структуры A не резервируется?

Добавлено через 6 минут
vlisp, только что скомпилил без ошибок.

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
#include <iostream>
 
using namespace std;
 
class P
{   
public:
    virtual int f(int a, int = 0)
    {
        cout << a;
    }
};
 
class C : P
{
public:
    int f(int a, int b) override
    {
        P::f(a, b);
        cout << b;
    }
};
 
int main()
{
    P p;
    C c;
    
    p.f(10, 0);
    c.f(20, 30);
    
    return 0;
}
0
Модератор
Эксперт С++
10871 / 8990 / 5408
Регистрация: 18.12.2011
Сообщений: 24,029
17.08.2019, 07:39 7
1.
Цитата Сообщение от rjomendrive_ Посмотреть сообщение
c.f(20, 30);
это явный вызов функции производного класса без использования полиморфизма.

Надо так:
C++
1
2
P* x=&c;
x->f(20,30);
2. Кроме того, не получится использовать private наследование,
придется писать:
C++
1
class C : public P
3. Ну и не
C++
1
int f(....
а
C++
1
void f(...
0
0 / 0 / 0
Регистрация: 28.03.2019
Сообщений: 9
17.08.2019, 07:49  [ТС] 8
zss, точно! Затупил немного)

Добавлено через 7 минут
zss, спасибо. В любом случае, это работает.

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>
 
using namespace std;
 
class P
{   
public:
    virtual void f(int a, int = 0)
    {
        cout << a;
    }
};
 
class C : public P
{
public:
    void f(int a, int b) override
    {
        P::f(a, b);
        cout << b;
    }
};
 
int main()
{
    P p;
    P* p_ptr = new C;
    
    p.f(10);
    p_ptr->f(20, 30);
    
   delete p_ptr;
    return 0;
}
0
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
17.08.2019, 11:31 9
rjomendrive_, смысл полиморфизма в том, чтобы в месте вызова вопрос о том какой метод вызовется скрывался за фасадом указателя или ссылки на базовый класс. Это делает возможными такие вещи как итерации по контейнерам указателей на базовый класс с вызовом виртуального метода, например. С ссылками так не получится, но ссылки базового класса можно передавать в функции внутри которых дергается виртуальный метод. Важно то, что массовость алгоритма вызова состоит в том, что вызов записывается одной инструкцией и там придётся передать параметры одним единым образом. Вот почему, затея обеспечения виртуальности на разных (якобы) сигнатурах, логически ущербна. Способ с параметром по умолчанию остроумен, но по месту использования не пригодится, потому, что если будет жменя вызовов (с разными параметрами) и код заранее будет выяснять к какому указателю относится какой вызов, то весь полиморфизм пойдёт по свичам. Кроме того, аргумент по умолчанию на самом деле присутствует и передаётся. Ну и наконец, нельзя будет написать метод с одним аргументом, если потребуется, так как неоднозначность вызова уже организована для этого случая.
0
Эксперт С++
8401 / 4077 / 891
Регистрация: 15.11.2014
Сообщений: 9,165
17.08.2019, 14:24 10
Лучший ответ Сообщение было отмечено DrOffset как решение

Решение

Цитата Сообщение от rjomendrive_ Посмотреть сообщение
второй аргумент будет лишним в классе Parent, но будет нужным в классе Child.
ты осознаешь какой это бред?

что такое "наследование" в ООП?
это - модель, которая за оооочеееень редким исключением (не публичного наследования),
реализует отношение "являюсь".

например:
C++
1
class dog: public animal { ... };
наследник - дог, является животным.

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

это что за бред?

как такое могло произойти?
либо наследование кривое.
нельзя такую собаку наследовать от такого животного.

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

Цитата Сообщение от rjomendrive_ Посмотреть сообщение
Имена Parent и Child выбраны специально, чтобы никому не забивать голову ненужной информацией. Зачем тебе знать, для чего именно предназначены классы, если вопрос совсем другой?
затем, что:
Цитата Сообщение от hoggy Посмотреть сообщение
твои Child, Parent - это сферические кони в вакууме.
и сейчас твой вопрос звучит так:
"как мне сделать непонятную херню, непонятно зачем,
в условиях противоречия с логикой?"

ну можешь передавать 2 аргумента, 3 аргумента, 10ть аргументов, массив из аргументов.

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

или как порешать причину архитектурной проблемы?

если хочешь заниматься хернёй: std::vector<arg> спасет отца русской демократии.

а если хочешь решить настоящую проблему:
включай уже голову. и начинай соображать:
проблема не с аргументами. аргументы - следствие.
проблема с неверным наследованием не того дога, от не того животного.
0
"C with Classes"
1485 / 1287 / 485
Регистрация: 16.08.2014
Сообщений: 5,413
Записей в блоге: 1
17.08.2019, 21:52 11
я понял чо хочет хоги, короче берем массив и разделяем его как хотим, главное что бы не вылез за ....
https://www.youtube.com/watch?v=Do5MMmEygsY
0
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
18.08.2019, 00:44 12
Цитата Сообщение от _stanislav Посмотреть сообщение
берем массив и разделяем его как хотим
Массив беззащитен против силы разума.
По теме:
"Один интерфейс и много реализаций", это не "Много интерфейсов". То есть, желание преодолеть границу данной абстракции манит неотвратимо. Отрадно то, что в данном случае, общественность не разделилась и осталась на светлой стороне парадигмы.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.08.2019, 00:44

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

Полиморфизм
Является ли перегрузка функций полиморфизмом? Шаблонные функции тоже одна из разновидностей...

Полиморфизм
Всем доброго времени суток.Сразу к делу. Если описывать с помощью полиморфизма подклассы и потом...

Полиморфизм c++
Построить массив из указателей (базового типа) на объекты обоих классов. Выбрать объекты...

Полиморфизм.
Доброго времени суток. Помогите решить следующую задачку: Создать класс периодическое издание...


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

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

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