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

Доступ к данным потомка - C++

Восстановить пароль Регистрация
 
 
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 01:47     Доступ к данным потомка #1
Здравствуйте, коллеги!
В теме почти что полный 0, потому прошу сделать скидку

Есть базовый класс (CMyPoint), от него наследуют еще несколько (CMyStar,CMyFly и т.д.)
Создано несколько экземпляров (объектов?) всех этих классов, и все это свалено в объект-список CMyList
Его хедэр:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct SMyNode
{
    SMyNode *pNext;
    CMyPoint *pObj;
};
class CMyList
{
public:
    CMyList(void);
    ~CMyList(void);
    
    void AddList(CMyPoint *pNObject);
    void ShowAll(CDC *xdc);
    void MoveAll(CDC *xdc);
 
    SMyNode *pHead,*pCurr,*pTemp;
};
Проблема в том, что, находясь в классе CMyList, я могу добраться до методов родителя любого производного класса, (т.е. CMyPoint), но не методов потомка (к примеру, CMyStar), хотя в дебагере при отладке они есть, но даны в квадратных скобках [CMyStar]. Получается, в панели дебагера я раскрываю pCurr->pObj и имею все переменные и функции, описанные в классе-родителе CMyPoint плюс в квадратных скобках [CMyStar] - все хохяйство производного класса.
Прпостите, если не так описал
Теперь вопрос: как добраться в такой ситуации до переменных, уникальных для производного класса, т.е. не описанных в классе родителе?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
I.M.
 Аватар для I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
05.11.2013, 02:03     Доступ к данным потомка #2

Не по теме:

здесь идет бухтение о неправильной архитектуре


с помощью static_cast http://www.cplusplus.com/doc/tutorial/typecasting/
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.11.2013, 02:12     Доступ к данным потомка #3
Цитата Сообщение от I.M. Посмотреть сообщение
с помощью static_cast
dynamic_cast. Починил.
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 03:30  [ТС]     Доступ к данным потомка #4
А можно чуточку подробнее?

Добавлено через 1 час 4 минуты
Потому как вообще ничего не понял :-(((((
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 03:33     Доступ к данным потомка #5
почитай многое поймешь
http://www.e-reading.biz/book.php?book=1002058
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 03:37  [ТС]     Доступ к данным потомка #6
Пощадите! :-(
Я этого за разумное время не осилю
У меня есть конкретная задача, как из CMyList (класс, организующий кучу объектов, у которых родитель CMyPoint) добраться до членов класса-наследника от CMyPoint
Хороший пинок в нужном направлении
newbie666
Заблокирован
05.11.2013, 04:35     Доступ к данным потомка #7
Цитата Сообщение от SwanSONG Посмотреть сообщение
Есть базовый класс (CMyPoint), от него наследуют еще несколько (CMyStar,CMyFly и т.д.)
Создано несколько экземпляров (объектов?) всех этих классов, и все это свалено в объект-список CMyList
Его хедэр:
в чем проблема? по подробнее излагайте суть опроса
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 04:52  [ТС]     Доступ к данным потомка #8
Да куда уж подробнее...
Есть базовый класс CMyPoint:
C++
1
CMyPoint::CMyPoint(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int iR,int iG,int iB)
Несколько производных классов:
C++
1
CMyStar::CMyStar(int iiType,int iiPos,int iiColor,int iLimitX,int iLimitY,int iLimit,int ix,int iy,int iF,int iA,int iR1,int iR,int iG, int iB):CMyPoint(iiType,iiPos,iiColor,iLimit,ix,iy,iR,iG,iB)
C++
1
CMyFly::CMyFly(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int iR,int iG, int iB):CMyPoint(iiType,iiPos,iiColor,iLimit,ix,iy,iR,iG,iB)
И класс CMyList(объект-список), который собирает все это добро в кучу примерно так:
C++
1
pList->AddList(new CMyFly(t0,t1,t2,t3,t4,t5,t6,t7,t8));
Функция AddList:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CMyList::AddList(CMyPoint *pNObject)
{
    if(pHead==NULL)
    {
        pHead=new SMyNode;
        pHead->pNext=NULL;
        pHead->pObj=pNObject;
    }
    else
    {
        pCurr=pHead;
        while(pCurr->pNext!=NULL)
            pCurr=pCurr->pNext;
        pCurr->pNext=new SMyNode;
        pCurr=pCurr->pNext;
        pCurr->pNext=NULL;
        pCurr->pObj=pNObject;
    }
}
Структура SMyNode:
C++
1
2
3
4
5
struct SMyNode
{
    SMyNode *pNext;
    CMyPoint *pObj;
};
Потом в цикле идет просмотр всего списка (while(pCurr!=NULL)) и производяться некоторые действия над списком

Вопрос вот в чем:
Как из этого цикла в CMyList получить доступ к методам классов-потомков CMyPoint???
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.11.2013, 10:12     Доступ к данным потомка #9
Цитата Сообщение от SwanSONG Посмотреть сообщение
олучить доступ к методам классов-потомков CMyPoint???
да вроде написали уже
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
dynamic_cast.
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 10:17     Доступ к данным потомка #10
Цитата Сообщение от SwanSONG Посмотреть сообщение
Есть базовый класс CMyPoint:
где? показывай
Цитата Сообщение от SwanSONG Посмотреть сообщение
Несколько производных классов:
то же показывай
Цитата Сообщение от SwanSONG Посмотреть сообщение
ак из этого цикла в CMyList получить доступ к методам классов-потомков CMyPoint???
виртуальные функции слыхал?
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 11:53  [ТС]     Доступ к данным потомка #11
To ValeryS:

CMyPoint.h
Кликните здесь для просмотра всего текста
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
#pragma once
 
#include "afxwin.h"
 
class CMyPoint
{
public:
    CMyPoint(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int iR,int iG,int iB);
    ~CMyPoint();
 
    virtual void Show(CDC *xdc);
    virtual void Hide(CDC *xdc);
    virtual void xSetPrivate(void);
 
    void xSetCommon(int dx,int dy,int dR,int dG,int dB);
    void Move(int dx,int dy,int dR,int dG,int dB,CDC *xdc); 
 
    CDC *xdc;
 
    int idType,idPos,idColor;
    int xLimit,xCount;
    int x,y;
    int cR,cG,cB;
};


CMyPoint.cpp:
Кликните здесь для просмотра всего текста
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
#include "afxwin.h"
 
#include "CMyPoint.h"
#include "CMyPoint.h"
 
CMyPoint::CMyPoint(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int iR,int iG,int iB)
{
    idType=iiType;
    idPos=iiPos;
    idColor=iiColor;
 
    xLimit=iLimit;
    xCount=0;
    x=ix;
    y=iy;
    cR=iR;
    cG=iG;
    cB=iB;
}
 
CMyPoint::~CMyPoint()
{}
 
void CMyPoint::Show(CDC *xdc)
{
    xdc->SetPixel(x,y,RGB(cR,cG,cB));
}
 
void CMyPoint::Hide(CDC *xdc)
{
    xdc->SetPixel(x,y,RGB(6,38,77));
}
 
void CMyPoint::xSetCommon(int dx,int dy,int dR,int dG,int dB)
{
    x+=dx;
    y+=dy;
    cR+=dR;
    cG+=dG;
    cB+=dB;
}
 
void CMyPoint::xSetPrivate()
{
    xCount++;
    if(xCount>=xLimit)
    {
        xCount=0;
        x=rand()%1000;
        y=rand()%800;
        xLimit=rand()%600;
    }
}
 
void CMyPoint::Move(int dx,int dy,int dR,int dG,int dB, CDC *xdc)
{
    Hide(xdc);
    xSetCommon(dx,dy,dR,dG,dB);
    xSetPrivate();
    Show(xdc);
}


Производный
CMyFly.h:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once
#include "cmypoint.h"
 
class CMyFly:public CMyPoint
{
public:
    CMyFly(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int cR,int cG,int cB);
    ~CMyFly();
 
    virtual void Show(CDC *xdc);
    virtual void Hide(CDC *xdc);
    virtual void xPrint(CDC *xdc);
    virtual void xSetPrivate(void);
 
    int xLimit;
    int xCount;
};


CMyFly.cpp
Кликните здесь для просмотра всего текста
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 "afxwin.h"
#include "CMyPoint.h"
#include "CMyFly.h"
 
CMyFly::CMyFly(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int iR,int iG, int iB):CMyPoint(iiType,iiPos,iiColor,iLimit,ix,iy,iR,iG,iB)
{
    xLimit=iLimit;
    xCount=0;
}
 
CMyFly::~CMyFly()
{}
 
void CMyFly::Show(CDC *xdc)
{
    xdc->SetPixel(x,y,RGB(cR,cG,cB));
}
 
void CMyFly::Hide(CDC *xdc)
{
    xdc->SetPixel(x,y,RGB(6,38,77));
}
 
void CMyFly::xPrint(CDC *xdc)
{}
 
void CMyFly::xSetPrivate()
{
    xCount++;
    if(xCount>=xLimit)
    {
        x=rand()%200+400;
        y=rand()%200+300;
        xCount=0;
 
        if((x>=500)&&(y<400))
            idPos=1;
        if((x>=500)&&(y>=400))
            idPos=2;
        if((x<500)&&(y>=400))
            idPos=3;
        if((x<500)&&(y<400))
            idPos=4;
    }
}

Другие производные классы - по аналогии

"виртуальные функции слыхал?"
"Слыхал", но ведь написал в начале: почти чайник и попросил на это сделать скидку
Какая тут связь? Я так понимаю, что желаемое можно получить через dynamic_cast, но я не могу понять, как
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 12:30     Доступ к данным потомка #12
Цитата Сообщение от SwanSONG Посмотреть сообщение
CMyPoint.h
деструктор тоже виртуальный нужен
Цитата Сообщение от SwanSONG Посмотреть сообщение
"виртуальные функции слыхал?"
"Слыхал", но ведь написал в начале: почти чайник и попросил на это сделать скидку
объясняю на пальцах
виртуальная функция вызовет нужна для того чтобы вызвать функцию объекта, а не базового класса
например
C++
1
2
3
CMyFly ob1;
CMyPoint * ob2=&ob1;
ob2->xSetPrivate();
в данном случае вызовется функция xSetPrivate из класса CMyFly
а если бы функция была не виртуальная то вызвалась бы функция из CMyPoint
при виртуальных функциях компилятор сам решит из какого класса вызвать функцию
лишних действий со стороны программиста не требуется
главное чтобы функция была определена и в базовом классе и классе наследнике и объявлена как виртуальная
с членами класса сложнее
но можно создать виртуальную функцию которая вернет члены класса
какой нибудь GetInfo

Добавлено через 8 минут
Цитата Сообщение от SwanSONG Посмотреть сообщение
Я так понимаю, что желаемое можно получить через dynamic_cast, но я не могу понять, как
пойми что указатель указывает на базовый класс, в котором нет половины информации
и чтобы достать эту информацию компилятор должен знать на какой класс указатель действительно указывает
чтобы найти информацию о классе и нужен dynamic_cast
вот так лежит объект в памяти
Код
..............................
. -------------------   .
. -- базовый класс--   .
. -- int a       --   .
. -------------------   .
. ++++++++++++++++++ .
. + класс наследник + .
. + int b           + .
. ++++++++++++++++++.
.................................
указатель указывает на базовый класс ( все что в минусе)
про наследника (все что в плюсе) никто ничего не знает
чтобы узнал нужно привести
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 12:31  [ТС]     Доступ к данным потомка #13
Это-то я понял
Виртуальная функция перекрывает функцию родителя, т.е. при вызове функции будет вызвана функция потомка, хотя в родителе она тоже описана
У меня общие только xSetComon и Move. Move крутиться в цикле в CMyList

Проблема (для меня) в том, что, находясь в CMyList, конструкция
C++
1
2
CMyPoint *ptr = new CMyFly;
dynamic_cast<CMyFly*>(ptr);
не прокатывает, потому как CMyList ничего не знает про наличие этого самого CMyFly
P.S. Пример от Алены (http://alenacpp.blogspot.com/2005/08/c.html)
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 12:33     Доступ к данным потомка #14
Цитата Сообщение от SwanSONG Посмотреть сообщение
не прокатывает, потому как CMyList ничего не знает про наличие этого самого CMyFly
дак дай ей заголовочный файл того класса который она не знает
иначе откуда информацию брать
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 12:40  [ТС]     Доступ к данным потомка #15
Дописал в include
C++
1
#include "CMyFly.h"
во фрагменте
C++
1
2
CMyPoint *ptr = new CMyFly;
dynamic_cast<CMyFly*>(ptr);
ругается на CMyFly в конце первой строчки
error: no default constructor exist for class "CMyFly"
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 13:08     Доступ к данным потомка #16
Цитата Сообщение от SwanSONG Посмотреть сообщение
error: no default constructor exist for class "CMyFly"
а теперь смотрим
Цитата Сообщение от SwanSONG Посмотреть сообщение
CMyFly(int iiType,int iiPos,int iiColor,int iLimit,int ix,int iy,int cR,int cG,int cB);
конструктор с параметрами
а ты вызываешь без параметров
вот он и говорит нет такого
C++
1
CMyPoint *ptr = new CMyFly(1,2,3,4,5,6,7,8,9);
вот так вызывать должен
значения конечно взяты от балды, свои подставь
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 21:58  [ТС]     Доступ к данным потомка #17
Огромное спасибо за помощь, победил!!! (победили?)
В CMyList::MoveAll (здесь крутится цикл) дописал в начало:
C++
1
CMyPoint *ptr;
Потом нашли объект, который НЕ CMyPoint (idType задается в CMainWnd):
C++
1
if(ptr->idType==1)
А потом dynamic_cast:
C++
1
CMyFly *ptr1=dynamic_cast<CMyFly*>(ptr);
После этого ptr1 содержит в себе собственные данные именно CMyFly!!!!!

Еще раз ОГРОМНОЕ спасибо, все получилось именно так, как хотел!!!
А то были дурные мысли в конструкторе базового класса прописать ВСЁ барахло от потомков, но эта идея мне показалась некошерной....

Можно считать, тема закрыта

Добавлено через 8 часов 20 минут
Опять грабли :-((((
Когда добавил еще один класс-потомок, то преобразование формально работает, но в дебагере - Unable to read memory
Это я накосячил?

Добавлено через 12 минут
Сейчас проверил - значение все-таки меняется, но в дебагере все равно унайбл.
Походу, глюк дебагере или глюк самой студии (у меня VS 2012 Ultimate + W8.1)
Как-то можно исправить ситуацию?
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 22:07     Доступ к данным потомка #18
Цитата Сообщение от SwanSONG Посмотреть сообщение
Когда добавил еще один класс-потомок, то преобразование формально работает, но в дебагере - Unable to read memory
сразу же первый вопрос отлаживаешь Релиз версию или Дебиг?
SwanSONG
2 / 2 / 0
Регистрация: 30.01.2013
Сообщений: 36
05.11.2013, 22:13  [ТС]     Доступ к данным потомка #19
Дебаг
По факту все работает, но если верить дебагеру - нет
М.б. конфликт с Виндой? Все же в списке поддерживаемых осей 8.1 нет
Попробую поставить VS2013
Или есть иные решения - процесс замены студии - не быстрый
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.11.2013, 22:17     Доступ к данным потомка
Еще ссылки по теме:

Система складского учёта, доступ к данным и контроль над утилитами C++
C++ Наследование классов. Доступ к данным базового класса
доступ к protected функции из потомка C++

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

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
05.11.2013, 22:17     Доступ к данным потомка #20
Цитата Сообщение от SwanSONG Посмотреть сообщение
Походу, глюк дебагере или глюк самой студии (у меня VS 2012 Ultimate + W8.1)
у меня нет ни того ни другого не могу ничего сказать
да и скриншотик бы неплохо посмотреть
Yandex
Объявления
05.11.2013, 22:17     Доступ к данным потомка
Ответ Создать тему
Опции темы

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