Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сделать объект одного класса, чтобы он был виден в нескольких других 
:(
    Опции темы
Darked
Дата 29.10.2004, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 26.2.2004
Где: Южный Урал

Репутация: нет
Всего: нет



Всем Доброе время суток.
Чего - то я запутался. Есть класс главного фрейма CMainFrame, в нем создаются два класса CDIsplay и CIndexLat_w32View, в CDisplay создается определенный объект CObject, в который я загружаю некоторые данные. Создаю объект другого класса m_Integral в CIndexLat_w32View,теперь вопрос: Как мне получить данные из Cobject в m_Integral???

Что - то типа того:
Код

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
 public CMessageFilter, public CIdleHandler
{
public:

  CIndexLat_w32View    m_view;
  CDisplay      m_disp;
...
}


class CDisplay : public CScrollWindowImpl<CDisplay>
{

public:
...
  CObject t;
...
}


class CIndexLat_w32View : public CDialogImpl<CIndexLat_w32View>
{
public:
...
CIntegral m_Integral;  //закладка коррекции
...
}



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


--------------------
Veni, Vidi, Vici !!!
PM MAIL ICQ   Вверх
Step
Дата 29.10.2004, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



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

в CIntegral нужно получить радителя... потом из радителя получить еще одного родителя в результате вы попадете в маин фрейм.. этот указатель нужно преобразовать к (CMainFrame*)
после этого через этот указатель вы получаете доступ к m_disp а уже через него к t


это все я называю "достоинством :( МФЦ"
Добавлено @ 10:24
можно глабальными поиграться можно из класс получать указатель на класс создателя с преобразованием типа потом используя этот указатель выбирать нужный объект и пошло и поехало... подобных уровней может быть много все зависит от иерархии объектов...

в CIntegral нужно получить радителя... потом из радителя получить еще одного родителя в результате вы попадете в маин фрейм.. этот указатель нужно преобразовать к (CMainFrame*)
после этого через этот указатель вы получаете доступ к m_disp а уже через него к t


это все я называю "достоинством :( МФЦ"


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
Darked
Дата 29.10.2004, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 26.2.2004
Где: Южный Урал

Репутация: нет
Всего: нет



Step
Да уж, мне тоже бы не хотелось тянуть весь это хвост с указателями. Кстати, это не MFC, я в WTL пишу ;) Правда от этого не легче ;((((


--------------------
Veni, Vidi, Vici !!!
PM MAIL ICQ   Вверх
bel_nikita
Дата 29.10.2004, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Darked
Так может CObject - объявить виртуальным производным для классов class CDisplay и class CIndexLat_w32View?

Типа:
class CDisplay : virtual public CObject {};
class CIndexLat_w32View : virtual public CObject {};
И тогда CObject - будет одним объектом, но доступ к нему имеют CDisplay и CIndexLat_w32View

В общем понял идею, я думаю :)


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Mad
Дата 29.10.2004, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 7
Всего: 19



Darked
Тебе всеравно придется передовать классу CIndexLat_w32View, а через него CIntegral указатель на класс CDisplay, иначе получается неопределенность с обьектами класса.
Как альтернатива, если это приминимо, обьявить переменную как static
Код

class CDisplay : public CScrollWindowImpl<CDisplay>
{

public:
...
static CObject t;
...
}

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


--------------------
user posted image
PM MAIL   Вверх
Step
Дата 29.10.2004, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



я сам с этим вечно мучаюсь.. может вам сделать СДИ там хоть документ из любого вида получаеться... в него можно вбить все что вас интересует


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
Mad
Дата 29.10.2004, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 7
Всего: 19



Step
Насчет хранение в документе это мысль, хотя просто получается перемена мест хранение указателя (не у себя, а гдето, куда можно всегда добраться :) )

Цитата(Step @ 29.10.2004, 12:05)

может вам сделать СДИ там хоть документ из любого вида получаеться...

Вобщем получить все открытые документы можно и в MDI приложении :)



--------------------
user posted image
PM MAIL   Вверх
Darked
Дата 29.10.2004, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 26.2.2004
Где: Южный Урал

Репутация: нет
Всего: нет



bel_nikita
Ну у меня не совсем CObject, этот объект описан в не моей либе, мне просто предоставляют определенный тип данных.
Да и идею с virtual не совсем понял.
Добавлено @ 12:19
Step
Понимаете ли в чем дело, я пишу в WTL, там нет архитектуры Документ/Вид. А приложение у меня и так SDI ;)))


--------------------
Veni, Vidi, Vici !!!
PM MAIL ICQ   Вверх
bel_nikita
Дата 30.10.2004, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Darked
Цитата
Ну у меня не совсем CObject, этот объект описан в не моей либе, мне просто предоставляют определенный тип данных.
Да и идею с virtual не совсем понял.

CObject - трогать не будем, его просто объявляем vitrual'ым базовым классом для классов CDisplay и CIndexLat_w32View.

Допустим у нас уже есть класс CObject с двумя методами:
Код
class CObject
{
public:
   CObject(){ m_Value = 0; }
 ~virtual CObject(){}

 int   GetValue() { return m_Value; }
 void  SetValue(int iValue) { m_Value = iValue; }

private:
 int m_Value;
};


Для того чтобы не использовать глобальных объектов и квалификаторов friend немного извратимся :) . Поступаем следующим образом:
1. Объявляем CObject виртуальным для CDisplay:
Код
class CDisplay : virtual public CObject
{
public:
   CDisplay(){};
 ~ virtual CDisplay(){};

 CDisplay* GetMyPtr() { return this; }

 void CDisplayChangeCObject(int iValue) // специфичный метод для класса CDisplay
 {
   CObject::SetValue(iValue);
 }

 int GetValueChangedCDisplay() { return CObject::GetValue(); } // второй специфичный метод для класса CDisplay
};

2. Объявляем CObject виртуальным для CIndexLat_w32View:
Код
class CIndexLat_w32View : virtual public CObject
{
public:
   CIndexLat_w32View(){};
 ~ virtual CIndexLat_w32View(){};

 CIndexLat_w32View* GetMyPtr() { return this; }

 void CIndexLatChangeCObject(int iValue) // специфичный метод для класса CIndexLat_w32View
 {
   CObject::SetValue(iValue);
 }

 int GetValueChangedCIndexLat() { return CObject::GetValue(); } // второй специфичный метод для класса CIndexLat_w32View
};

3. А сейчас самое интересное :) . Создаем класс-обертку. В нем будет два метода, которые нам пригодяться в последствии, больше от этого класса нам ничего не нужно:
Код
class D3: public CDisplay, public CIndexLat_w32View
{
public:
   D3(){};
 ~ D3(){};

 CDisplay*           GetDisplay() { return CDisplay::GetMyPtr(); } // получение поинтера на CDisplay
 CIndexLat_w32View*  GetIndexLat_w32View() { return CIndexLat_w32View::GetMyPtr(); } // получение поинтера на CIndexLat
};

4. Это все :) . Теперь из класса CIndexLat_w32View имеем доступ к данным CObject и из класса CDisplay к данным CObject. Причем объект CObject - один для всех производных классов

Теперь можно протестировать:
Код

int main(int argc, char* argv[])
{

 CDisplay*           pDisplay; // поинтер на CDisplay
 CIndexLat_w32View*  pIndexLat_w32View; // поинтер на CIndexLat_w32View

 D3*                 pD3; // поинтер на обертку

 int iTemp;   // Тестовая переменная

 pD3               = new D3(); // создаем все, что нам нужно за один раз :)

 pDisplay          = pD3->GetDisplay(); // получаем поинтер на объект CDisplay
 pIndexLat_w32View = pD3->GetIndexLat_w32View(); // получаем поинтер на объектGetIndexLat_w32View

 iTemp = pDisplay->GetValue(); // Доступ из объекта СDisplay к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0х0000 - правильно

 iTemp = pIndexLat_w32View->GetValue(); // Доступ из объекта CIndexLat... к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0х0000 - правильно

 pDisplay->SetValue(0xFFFF); // Изменяем CObject из СDisplay
 iTemp = pIndexLat_w32View->GetValue(); // Доступ из объекта CIndexLat... к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0xFFFF - правильно

 pIndexLat_w32View->SetValue(0xAAAA); // Изменяем CObject из IndexLat...
 iTemp = pDisplay->GetValue(); // Доступ из объекта СDisplay к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0xAAAA - правильно

 pDisplay->CDisplayChangeCObject(0xBBBB); // Изменяем CObject из СDisplay
 iTemp = pIndexLat_w32View->GetValueChangedCIndexLat(); // Доступ из объекта CIndexLat... к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0xBBBB - правильно

 pIndexLat_w32View->CIndexLatChangeCObject(0xCCCC); // Изменяем CObject из IndexLat...
 iTemp = pDisplay->GetValueChangedCDisplay(); // Доступ из объекта СDisplay к объекту CObject
 printf("\niTemp =%08X",iTemp); // получаем 0xCCCC - правильно

 delete pD3; // очистили память одним махом :)
}


Вот, вроде, то, что требовалось доказать, т.е. никаких static'ов и friend'ов. CIndexLat_w32View и CDisplay могут одновременно свободно юзать CObject. Т.е. если раньше объект CObject был доступен только CDisplay, то теперь и CIndexLat_w32View имеет к нему доступ. :)


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Mad
Дата 30.10.2004, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 7
Всего: 19



bel_nikita
Вопервых твой пример и так франит указатели (ну не в переменных, так в VTABLE).
Вовторых требует создание дополнительного класса (и соответственно обьекта).
Втретьих это верно только для равного количества классов CDisplay и CIndexLat_w32View. (Тебе прийдется создавать класс оболочку для кожой комбинации этих классов).
Ну и наконец, в твоем примере классы связанны намертво. (т.е невозможно заминить связи в уже созданых обьектах).

Есть такой вариант :)

Код

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
public:

CDisplay   m_disp;
CIndexLat_w32View  m_view(&m_disp.t);
...
}


class CDisplay : public CScrollWindowImpl<CDisplay>
{

public:
...
CObject t;
...
}

class CIntegral
{
public:
CIntegral(CObject *pObject):m_pObject(pObject){};
...
CObject *m_pObject;
}

class CIndexLat_w32View : public CDialogImpl<CIndexLat_w32View>
{
public:
...
CIndexLat_w2View(CObject *pObject);
CIntegral m_Integral; //закладка коррекции
...
}



--------------------
user posted image
PM MAIL   Вверх
bel_nikita
Дата 30.10.2004, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Mad
Понятно, что есть. Это один из вариантов.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Darked
Дата 2.11.2004, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 26.2.2004
Где: Южный Урал

Репутация: нет
Всего: нет



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


--------------------
Veni, Vidi, Vici !!!
PM MAIL ICQ   Вверх
Step
Дата 3.11.2004, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



Цитата(Darked @ 29.10.2004, 12:16)


там нет архитектуры Документ/Вид. А приложение у меня и так SDI ;)))


:)


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.