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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
#1

ООП + полиморфизм = wtf? - C++

27.08.2011, 19:49. Просмотров 1913. Ответов 40
Метки нет (Все метки)

Есть:
Класс A - отец
Класс Б - дочерний
Класс Ц - дочерный, наследуеться от А(сестра Б)

Есть массив типа А, с названием Mass.
Он хранит в себе объекты классов Б и Ц.

в классе Б есть функция F().
в классе Ц есть функция F() (отличающаяся функционалом).

Внамание! Вопрос:
как провернуть такую часть кода - Mass[0..100].F();
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.08.2011, 19:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос ООП + полиморфизм = wtf? (C++):

ООП. Полиморфизм - C++
Мальчики, учусь на МехМате. Для сдачи зачёта по ООП необходимо написать последнюю программу: Задание: полиморфизм Указание: во всех...

ООП Полиморфизм Наследование - C++
У меня есть базовый класс и 2 производных от него класса... Как сделать, чтобы в программе я мог сделать такое обьявление: Force fc;...

Полиморфизм инкапсуляция и наследование(ООП) - C++
Не как не могу понять зачем нужен Полиморфизм и инкапсуляция и их определение может вы подскажите, наследования я знаю

Подкиньте практику по ООП + полиморфизм + шаблоны пожалуйста. - C++
Здравствуйте форумчане. Хотел бы попросить подбросить практику по таким темам: ООП - полифорфизм + Тэмплэты. Ну и если можно, что нибудь...

ООП в С++ (наследование, инкапсуляция, полиморфизм, перегрузка операторов): что читать? - C++
Нужно освежить, подзабылось. Были у меня институцкие методички доцента Шеховцова. Хороша вещь, но потерялись. Нужны либо набор...

Очередное WTF ))) - C++
Вот до чего меня жизнь довела: имеем файл file.txt который содержит просто строку "Hello,World!" (с ковычками). Далее пишем такой код: ...

40
Bers
Заблокирован
27.08.2011, 20:15 #16
Цитата Сообщение от grizlik78 Посмотреть сообщение
Да у него эта функция для "дитя". Внутри определения класса.
Аааа... точна-точна. Действительно!

В общем, если кратко: класс А должен содержать интерфейс управления всем семейством полиморфных классов.

А класс Б, как потомок класса А - лишь конкретные реализации виртуальных методов класса А.
И тогда все будит нормально.
0
Сыроежка
Заблокирован
27.08.2011, 20:16 #17
Цитата Сообщение от BAIZOR Посмотреть сообщение
А если юзать в вызове ->


Error 23 error C2819: type 'D3D_UI' does not have an overloaded member 'operator ->' c:\users\baizor\desktop\robotino v3 directx 9 - копия\robotino v2 directx 9\Direct_All.h 710 1 Robotino V2 Directx 9
Это сообщение ясно, почему берется. Вы пытаетесь к объекту класса применить оператор ->, а в вашем классе этот оператор не определен. То есть у вас изначально неправильная конструкция. Наверное, когда вы формировали свой массив типа A, вы присваивали его элементам объекты класса B и C. Но в этом случае происходила "срезка", то есть в элементы вашего массива заносились лишь базовый класс ваших производных классов B и C.

Может быть вам следуеть базовый класс A объявить как абстрактный, и тогда бы вы такой ошибки неправильной конструкции массива не допустили бы, так как на этапе компиляции компилятор выловил бы такую ошибку, как объявление массива типа A и присваивание его элементам производных классов B и C.
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,007
27.08.2011, 20:18 #18
Цитата Сообщение от BAIZOR Посмотреть сообщение
UI == Mass

C++
1
2
D3DXButton Connect(...);
UI.push_back(Connect);
Да, да. Пока именно "срезка" и получается.
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:20  [ТС] #19
Цитата Сообщение от Сыроежка Посмотреть сообщение
Это сообщение ясно, почему берется. Вы пытаетесь к объекту класса применить оператор ->, а в вашем классе этот оператор не определен. То есть у вас изначально неправильная конструкция. Наверное, когда вы формировали свой массив типа A, вы присваивали его элементам объекты класса B и C. Но в этом случае происходила "срезка", то есть в элементы вашего массива заносились лишь базовый класс ваших производных классов B и C.
Спасибо, мне предложили этот вариант, и я просто продемонтрировал что он не рабочий.




Я уже понял все, только одного не знаю - как сделать класс Абстрактным, я давненько это делал... в нем не может быть не абстрактных функций и еще что-то ?
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.08.2011, 20:20 #20
BAIZOR, в нём должна быть хотя бы одна чисто виртуальная функция.
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:22  [ТС] #21
C++
1
2
3
4
abstract class D3D_UI
{
      virtual void setStatus(LPVOID Object,int newstatus) = 0;
};


this declaration has no storage class or type specifier c:\users\baizor\desktop\robotino v3 directx 9 - копия\robotino v2 directx 9\direct3d_ui.h 1 1 Robotino V2 Directx 9



позабыл я как это делаеться?
0
Сыроежка
Заблокирован
27.08.2011, 20:25 #22
Цитата Сообщение от BAIZOR Посмотреть сообщение
Спасибо, мне предложили этот вариант, и я просто продемонтрировал что он не рабочий.

Я уже понял все, только одного не знаю - как сделать класс Абстрактным, я давненько это делал... в нем не может быть не абстрактных функций и еще что-то ?

Вы можете в своем базовом классе функцию setStatus объявить следующим образом

C++
1
virtual void setStatus(LPVOID Object,int newstatus) = 0;
Это между прочим не мешает вам опеределить в базовом классе тело самой функции, если есть такая необходимость, то есть если в производных классах в этой функции используется вызов setStatus из их кода.

Добавлено через 1 минуту
Цитата Сообщение от BAIZOR Посмотреть сообщение
C++
1
2
3
4
abstract class D3D_UI
{
      virtual void setStatus(LPVOID Object,int newstatus) = 0;
};


this declaration has no storage class or type specifier c:\users\baizor\desktop\robotino v3 directx 9 - копия\robotino v2 directx 9\direct3d_ui.h 1 1 Robotino V2 Directx 9



позабыл я как это делаеться?
Больше ничего добавлять не надо. Достаточно одну функцию объявить чисто виртуальной. Проще всего это сделать для деструктора класса.
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:26  [ТС] #23
Цитата Сообщение от Сыроежка Посмотреть сообщение
Это между прочим не мешает вам опеределить в базовом классе тело самой функции, если есть такая необходимость, то есть если в производных классах в этой функции используется вызов setStatus из их кода.
хм... мудро, учту

Добавлено через 42 секунды
Цитата Сообщение от Сыроежка Посмотреть сообщение
Больше ничего добавлять не надо. Достаточно одну функцию объявить чисто виртуальной. Проще всего это сделать для деструктора класса.
да, но ошибка, вон, я дописал под кодом
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,007
27.08.2011, 20:26 #24
Цитата Сообщение от BAIZOR Посмотреть сообщение
позабыл я как это делаеться?
Слово abstract зачем?
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:29  [ТС] #25
Цитата Сообщение от Сыроежка Посмотреть сообщение
this declaration has no storage class or type specifier

=(....

Добавлено через 52 секунды
Цитата Сообщение от grizlik78 Посмотреть сообщение
Слово abstract зачем?
убрал - 'D3D_UI' : cannot instantiate abstract class

Добавлено через 37 секунд
опять же, вопрос, разве ничего больше не надо для абстрактного класса?

Добавлено через 29 секунд
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class D3D_UI
{
protected:
    UINT                        status;
    LPDIRECT3DTEXTURE9          sleep,activ,down;
    LPDIRECT3DVERTEXBUFFER9     g_pVB;
    bool                        enable;
    time_t                      timer;
    bool                        (*function)(Robotino3D*);
 
public:
    D3DRectangle                Rectangle;
    bool                        Down;
 
    D3D_UI(){status=0;}
    D3D_UI(LPDIRECT3DDEVICE9 &pd3dDevice,
                                        LPCWSTR sleep_,
                                        LPCWSTR activ_,
                                        LPCWSTR down_, 
                                        float x1, 
                                        float y1, 
                                        float z1, 
                                        float x2,
                                        float y2,
                                        float z2,
                                        float z3,
                                        float z4)
    {
        UpdateObject(pd3dDevice, sleep_, activ_, down_, x1, y1, z1, x2, y2, z2, z3, z4);
    }
 
    static void TransformCoords(LPDIRECT3DDEVICE9 &pd3dDevice, 
                                D3DCamera &Camera, 
                                D3DXMATRIX &Transform, 
                                D3DXVECTOR3 &pos, 
                                D3DXVECTOR3 &dir, 
                                int x, 
                                int y)
    {
        float                       px,
                                    py;
 
        D3DVIEWPORT9                ViewPort;
        D3DXMATRIX                  MatrixProjection;
 
        pd3dDevice->GetViewport     (&ViewPort);
        pd3dDevice->GetTransform    (D3DTS_PROJECTION, &MatrixProjection);
 
        px      =   ((( 2.0f*(float)x) / (float)ViewPort.Width)  - 1.0f) / MatrixProjection._11;
        py      =   (((-2.0f*(float)y) / (float)ViewPort.Height) + 1.0f) / MatrixProjection._22;
 
        pos.x   =   Camera.CamPos.x; 
        pos.y   =   Camera.CamPos.y; 
        pos.z   =   Camera.CamPos.z;
  
        dir.x   =   px; 
        dir.y   =   py; 
        dir.z   =   1.0;
 
        D3DXVec3TransformCoord( 
          &pos, 
          &pos, 
          &Transform 
        ); 
  
        D3DXVec3TransformNormal( 
          &dir, 
          &dir, 
          &Transform 
        );
    }
    virtual void setStatus(LPVOID Object,int newstatus) = 0;
 
    bool Select(D3DXVECTOR3 &pos, D3DXVECTOR3 &dir)
    {
        float               Distance    =   2000.0f;
 
        CUSTOMVERTEX        *buffer     =   Rectangle.init();
 
        bool                Result_1    =   false,
                            Result_2    =   false;
 
        Result_1    =    D3DXIntersectTri   (   &D3DXVECTOR3(buffer[0].x, buffer[0].y, buffer[0].z), 
                                                &D3DXVECTOR3(buffer[1].x, buffer[1].y, buffer[1].z),
                                                &D3DXVECTOR3(buffer[2].x, buffer[2].y, buffer[2].z),
                                                &pos,
                                                &dir,
                                                0,
                                                0,
                                                &Distance);
 
        Result_2    =    D3DXIntersectTri   (   &D3DXVECTOR3(buffer[3].x, buffer[3].y, buffer[3].z), 
                                                &D3DXVECTOR3(buffer[4].x, buffer[4].y, buffer[4].z),
                                                &D3DXVECTOR3(buffer[5].x, buffer[5].y, buffer[5].z),
                                                &pos,
                                                &dir,
                                                0,
                                                0,
                                                &Distance);
 
        return Result_1 || Result_2;
    }
    void SetTimer(UINT t_size)
    {
        timer   =   clock() + t_size;
    }
    void UpdateObject(LPDIRECT3DDEVICE9 &pd3dDevice, 
                                        LPCWSTR sleep_,
                                        LPCWSTR activ_,
                                        LPCWSTR down_, 
                                        float x1, 
                                        float y1, 
                                        float z1, 
                                        float x2,
                                        float y2,
                                        float z2,
                                        float z3,
                                        float z4)
    {
        Down        = false;
        status      = 0;
        g_pVB       =   NULL;
        sleep       =   NULL;
        activ       =   NULL;
        down        =   NULL;
        D3DXCreateTextureFromFile(pd3dDevice,sleep_, &sleep);
        D3DXCreateTextureFromFile(pd3dDevice,activ_, &activ);
        D3DXCreateTextureFromFile(pd3dDevice,down_ , &down);
        Rectangle   = *new D3DRectangle(x1, y1, z1, x2, y2, z2, z3, z4);
    }
 
    LPDIRECT3DTEXTURE9 getTexture()
    {
        if(status == 0) return sleep;
        if(status == 1) return activ;
        if(status == 2) return down;
    }
    virtual bool Render(LPDIRECT3DDEVICE9 &pd3dDevice)
    {
        pd3dDevice->SetFVF              ( D3DFVF_CUSTOMVERTEX );
        pd3dDevice->SetStreamSource     ( 0, g_pVB, 0, sizeof(CUSTOMVERTEX));
 
        if(FAILED(pd3dDevice->SetTexture    (0, getTexture())))             return false;
        if(FAILED(pd3dDevice->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 2)))    return false;
 
        return true;
    }
};
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,007
27.08.2011, 20:31 #26
Цитата Сообщение от BAIZOR Посмотреть сообщение
убрал - 'D3D_UI' : cannot instantiate abstract class
Ну да. Потому что нельзя создать вектор с элементами этого типа. Можно и нужно создать вектор указателей на этот класс. Правда удалять элементы тогда вручную придётся.

Добавлено через 2 минуты
Кстати, возможно этот класс и не должен быть абстрактным. Это было просто предположение. Но потомков в один массив собрать можно только с помощью указателей.
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:33  [ТС] #27
Цитата Сообщение от grizlik78 Посмотреть сообщение
Потому что нельзя создать вектор с элементами этого типа.
Вот оно! Спасибо =)

Цитата Сообщение от grizlik78 Посмотреть сообщение
Правда удалять элементы тогда вручную придётся
А вызов деструктора из детей пойдет?
0
Сыроежка
Заблокирован
27.08.2011, 20:33 #28
Цитата Сообщение от BAIZOR Посмотреть сообщение
=(....

Добавлено через 52 секунды


убрал - 'D3D_UI' : cannot instantiate abstract class

Добавлено через 37 секунд
опять же, вопрос, разве ничего больше не надо для абстрактного класса?

Добавлено через 29 секунд
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class D3D_UI
{
protected:
    UINT                        status;
    LPDIRECT3DTEXTURE9          sleep,activ,down;
    LPDIRECT3DVERTEXBUFFER9     g_pVB;
    bool                        enable;
    time_t                      timer;
    bool                        (*function)(Robotino3D*);
 
public:
    D3DRectangle                Rectangle;
    bool                        Down;
 
    D3D_UI(){status=0;}
    D3D_UI(LPDIRECT3DDEVICE9 &pd3dDevice,
                                        LPCWSTR sleep_,
                                        LPCWSTR activ_,
                                        LPCWSTR down_, 
                                        float x1, 
                                        float y1, 
                                        float z1, 
                                        float x2,
                                        float y2,
                                        float z2,
                                        float z3,
                                        float z4)
    {
        UpdateObject(pd3dDevice, sleep_, activ_, down_, x1, y1, z1, x2, y2, z2, z3, z4);
    }
 
    static void TransformCoords(LPDIRECT3DDEVICE9 &pd3dDevice, 
                                D3DCamera &Camera, 
                                D3DXMATRIX &Transform, 
                                D3DXVECTOR3 &pos, 
                                D3DXVECTOR3 &dir, 
                                int x, 
                                int y)
    {
        float                       px,
                                    py;
 
        D3DVIEWPORT9                ViewPort;
        D3DXMATRIX                  MatrixProjection;
 
        pd3dDevice->GetViewport     (&ViewPort);
        pd3dDevice->GetTransform    (D3DTS_PROJECTION, &MatrixProjection);
 
        px      =   ((( 2.0f*(float)x) / (float)ViewPort.Width)  - 1.0f) / MatrixProjection._11;
        py      =   (((-2.0f*(float)y) / (float)ViewPort.Height) + 1.0f) / MatrixProjection._22;
 
        pos.x   =   Camera.CamPos.x; 
        pos.y   =   Camera.CamPos.y; 
        pos.z   =   Camera.CamPos.z;
  
        dir.x   =   px; 
        dir.y   =   py; 
        dir.z   =   1.0;
 
        D3DXVec3TransformCoord( 
          &pos, 
          &pos, 
          &Transform 
        ); 
  
        D3DXVec3TransformNormal( 
          &dir, 
          &dir, 
          &Transform 
        );
    }
    virtual void setStatus(LPVOID Object,int newstatus) = 0;
 
    bool Select(D3DXVECTOR3 &pos, D3DXVECTOR3 &dir)
    {
        float               Distance    =   2000.0f;
 
        CUSTOMVERTEX        *buffer     =   Rectangle.init();
 
        bool                Result_1    =   false,
                            Result_2    =   false;
 
        Result_1    =    D3DXIntersectTri   (   &D3DXVECTOR3(buffer[0].x, buffer[0].y, buffer[0].z), 
                                                &D3DXVECTOR3(buffer[1].x, buffer[1].y, buffer[1].z),
                                                &D3DXVECTOR3(buffer[2].x, buffer[2].y, buffer[2].z),
                                                &pos,
                                                &dir,
                                                0,
                                                0,
                                                &Distance);
 
        Result_2    =    D3DXIntersectTri   (   &D3DXVECTOR3(buffer[3].x, buffer[3].y, buffer[3].z), 
                                                &D3DXVECTOR3(buffer[4].x, buffer[4].y, buffer[4].z),
                                                &D3DXVECTOR3(buffer[5].x, buffer[5].y, buffer[5].z),
                                                &pos,
                                                &dir,
                                                0,
                                                0,
                                                &Distance);
 
        return Result_1 || Result_2;
    }
    void SetTimer(UINT t_size)
    {
        timer   =   clock() + t_size;
    }
    void UpdateObject(LPDIRECT3DDEVICE9 &pd3dDevice, 
                                        LPCWSTR sleep_,
                                        LPCWSTR activ_,
                                        LPCWSTR down_, 
                                        float x1, 
                                        float y1, 
                                        float z1, 
                                        float x2,
                                        float y2,
                                        float z2,
                                        float z3,
                                        float z4)
    {
        Down        = false;
        status      = 0;
        g_pVB       =   NULL;
        sleep       =   NULL;
        activ       =   NULL;
        down        =   NULL;
        D3DXCreateTextureFromFile(pd3dDevice,sleep_, &sleep);
        D3DXCreateTextureFromFile(pd3dDevice,activ_, &activ);
        D3DXCreateTextureFromFile(pd3dDevice,down_ , &down);
        Rectangle   = *new D3DRectangle(x1, y1, z1, x2, y2, z2, z3, z4);
    }
 
    LPDIRECT3DTEXTURE9 getTexture()
    {
        if(status == 0) return sleep;
        if(status == 1) return activ;
        if(status == 2) return down;
    }
    virtual bool Render(LPDIRECT3DDEVICE9 &pd3dDevice)
    {
        pd3dDevice->SetFVF              ( D3DFVF_CUSTOMVERTEX );
        pd3dDevice->SetStreamSource     ( 0, g_pVB, 0, sizeof(CUSTOMVERTEX));
 
        if(FAILED(pd3dDevice->SetTexture    (0, getTexture())))             return false;
        if(FAILED(pd3dDevice->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 2)))    return false;
 
        return true;
    }
};
Это означает, что где-то в коде main вы пытаетесь создать объект базового класса. Можно использовать лишь указатель на базовый класс или ссылку.
0
grizlik78
Эксперт С++
1956 / 1449 / 115
Регистрация: 29.05.2011
Сообщений: 3,007
27.08.2011, 20:36 #29
Цитата Сообщение от BAIZOR Посмотреть сообщение
А вызов деструктора из детей пойдет?
Пойдёт из детей, только деструктор должен быть объявлен в базовом классе как виртуальный. Для полиморфных классов это обязательно, кстати.
0
BAIZOR
0 / 0 / 0
Регистрация: 30.10.2010
Сообщений: 68
27.08.2011, 20:47  [ТС] #30
Цитата Сообщение от grizlik78 Посмотреть сообщение
Пойдёт из детей, только деструктор должен быть объявлен в базовом классе как виртуальный. Для полиморфных классов это обязательно, кстати.
Окей, спасибо большое!)
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2011, 20:47
Привет! Вот еще темы с ответами:

Расширение языка С. WTF? - C++
Hi, All! Решил на выходных заняться учебой, сессия скоро. На эти выходные наметил себе план работ - скачать задания:) Вот сижу читаю...

Спецификация файла. WTF? - C++
Здравствуйте. Что такое спецификация файла (в контексте данной задачи)? В Google ничего понятного не нашел. Заранее спасибо.

map assigment of read only data member или WTF? - C++
задача:из acm.timus.ru 1100. Таблица результатов Ограничение времени: 1.0 секунды Ограничение памяти: 16 МБ Старое программное...

WTF не работает простой код на Visual studio 2008(баг?) - C++
Взял код из википедии. ...


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

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
27.08.2011, 20:47
Ответ Создать тему
Опции темы

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