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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов в конструкторе методa класса 
:(
    Опции темы
knut
Дата 31.1.2007, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 7.2.2006

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



Добрый день.
Вот столкнулся с такой проблемой.
Есть класс   наследник класс CSomeClass(наследноков много)  и есть класс CParser у класса CParser есть метод 
void Load(const char*pFilename) // загрувает xml фаил. 
Теперь в конструкторе CSomeClass в вызваю метод CParser a Load(const char*pFilename) чтоб прочетать из фаила  данные  и инецализировать мемберы класса CSomeClass а.
Вопрос. 
Как передаьт в Load  метод обект SomeClass а ?в качестве парамерта Load a нельзя.
Код

class CSomeClass:public cBase
{
  CSomeClass()
{
  ob.Load(pFilename); // но в Load надо передать обект CSomeClass чтоб иницализовать 
                                  //мемберыданного класса
}
  
};
class cParser
{
   void Load(pfilename)
{
   //но здес нужен обект того класс чей конструктор вызвал Load()
   // парсим файл.
}
}



--------------------
Цитата

Многие вещи нам непонятны не оттого, что наши понятия слабы, а оттого, что данные вещи не входят в круг наших понятий.
PM MAIL   Вверх
Anikmar
Дата 31.1.2007, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Класс-родитель ничего не знает о методах и свойствах наследника. 
PM MAIL ICQ   Вверх
JackYF
Дата 31.1.2007, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(knut @  31.1.2007,  19:22 Найти цитируемый пост)
Как передаьт в Load  метод обект SomeClass а ?в качестве парамерта Load a нельзя.

почему?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Anikmar
Дата 31.1.2007, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Объект нельзя, а локальный параметр типа AnsiString можно
PM MAIL ICQ   Вверх
knut
Дата 1.2.2007, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 7.2.2006

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



Цитата

Класс-родитель ничего не знает о методах и свойствах наследника.

а ему  и не надо


--------------------
Цитата

Многие вещи нам непонятны не оттого, что наши понятия слабы, а оттого, что данные вещи не входят в круг наших понятий.
PM MAIL   Вверх
Daevaorn
Дата 1.2.2007, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

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



Цитата(knut @  1.2.2007,  12:31 Найти цитируемый пост)
а ему  и не надо 

вот тебе точно надо научиться по человечески задовать вопросы, если хочешь получать на них правильные ответы
PM MAIL WWW   Вверх
Vyacheslav
Дата 1.2.2007, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Что то тут с логикой не то. 
Я подобную систему решалпримерно так.  Исходим из того, что cParser
- это SAX парсер и при распарсивании он генерит события 
Тогда
Код

class CBase
typedef void (* EventHandler) (cBase*, const string& value); 
typedef map<string, EventHandler > Handlers;
typedef Handlers::value_type HandlersValue;  

class cBase
{
protected:
      //метод для регистриции обработчиков для присвоения( сеттеры) значения полям
       void field_register( const string& name,   EventHandler ) {
            m_handlers.insrteventHandler ( name,  EventHandler );
       }
public:
      // присваиваем полю с именем name значение value
       void set_field( const string& name, const string value ) {
            Handlers::iteratot result = m_handlers.find(name);
    if (result != m_handlers.end()) {
        EventHandler handler = (*result).second;
                                handler(this, value);
                }
       } 
private:
  Handlers m_handlers;
 };

class CSomeClass:public cBase
{
  CSomeClass()
 {
   //регистрируем обработчики для полей, появившихся в данном классе 
   field_register("a", set_a_member);
   field_register("b", set_a_member);
 }
  //обработчик, который выполняет присвоение полю
  // естесвенно, если поле не string, то в нем надо будет выполнить преобразование string to type
  static void set_a_member( CBase* obj,  string value) {
         if( CSomeClass *someClass = dynamic_cast<CSomeClass*>(obj) ) {
                a= value;
         }           
  }

   static void set_b_member( CBase* obj,  string value) {
         if( CSomeClass *someClass = dynamic_cast<CSomeClass*>(obj) ) {
                b= value;
         }           
  }
private: 
  string a;
  string b;
}

class CSomeClass1 :CSomeClass
{
  CSomeClass1()
 {
   //регистрируем обработчики для полей, появившихся в данном классе 
   field_register("c", set_c_member);
   field_register("d", set_d_member);
 }
  static void set_a_member( CBase* obj,  string value) {
         if( CSomeClass1 *someClass = dynamic_cast<CSomeClass1*>(obj) ) {
                c= value;
         }           
  }

   static void set_b_member( CBase* obj,  string value) {
         if( CSomeClass1 *someClass = dynamic_cast<CSomeClass1*>(obj) ) {
                d= value;
         }           
  }
private 
  string c;
  string d;
}


class cParser
{
   void Load(CBase* obj, pfilename )
   {
       // здесь  парсим и при получении имени поля и его значения name, value делаем присвоение
       obj->set_field(name, value);
   
   }
}



Код

 CSomeClass1  someClass;
  cParser().Load(&someClass, fileName);


А вообще можно еще  определить оператор >> 
Код

CSomeClass1  someClass;
 cParser(FileName) >> someClass;








--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
knut
Дата 1.2.2007, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 7.2.2006

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



есть класс cParser 
Код

class cParser 
{
public:
 void Load(const char *pFilename);
 void Add_Element(const char *pFilename,int x,int y,cBase::E_Type,cBase*);//Добавляет элемент в xml фаил   (т.е обект тира cUnit) 
};

елсть класс
Код


class cSomeClass:public cBase
{
  cSomeClass()
{ob.Add_element(.......,cSomeClass*)}//вызов Add_Element a 
 /// members
public:
        int value;
      ///....
  }


теперь если xотим создать обект т.е ( добавляем элемент в xml )
cSomeClass *pt = new cSomeClass; a в конструкторе cSomeClass вызеваем Аdd_Element(...,pt)
создали элемент и добавили в фаил.
Собственно  и вот проблема.
Надо инизализовать мемберы cSomeclass a после того как добавили элемент в фаил.


--------------------
Цитата

Многие вещи нам непонятны не оттого, что наши понятия слабы, а оттого, что данные вещи не входят в круг наших понятий.
PM MAIL   Вверх
Vyacheslav
Дата 1.2.2007, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(knut @  31.1.2007,  19:22 Найти цитируемый пост)
Есть класс   наследник класс CSomeClass(наследноков много)  и есть класс CParser у класса CParser есть метод 
void Load(const char*pFilename) // загрувает xml фаил. 
Теперь в конструкторе CSomeClass в вызваю метод CParser a Load(const char*pFilename) чтоб прочетать из фаила  данные  и инецализировать мемберы класса CSomeClass а.



Цитата(knut @  1.2.2007,  15:18 Найти цитируемый пост)

cSomeClass *pt = new cSomeClass; a в конструкторе cSomeClass вызеваем Аdd_Element(...,pt)
создали элемент и добавили в фаил.
Собственно  и вот проблема.




Не кажется Вам , что в эти два абзаца описывают совершенно противоположные процессы?
Первый абзац  описывант процедуру создания объекта и иyциализации его членов, данными из xml, что очень близко напоминает десериализацию
Второй  абзац больше похож на обратный процесс. 
Или я опять ничего не понял?





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Anikmar
Дата 1.2.2007, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

1 Вариант
Следовательно все эти свойства должны находиться в базовом классе, и этот метод спокойно их инициализирует. А передавать ему нужно объект базового класса.

2. Вариант
Если все производные классы, передаваемые в метод Add_Element имеют различные методы, которые требуются инициализировать - то тогда этот метод должен знать структуру переданного ему объекта. Т.е. в таком случае они тоже должны иметь общий базовый класс, а в методе Add_Element при помощи dynamic_cast  определеять конкретно какого класса объект был ему передан и инициализировать его.
PM MAIL ICQ   Вверх
Vyacheslav
Дата 1.2.2007, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Anikmar @  1.2.2007,  18:18 Найти цитируемый пост)
 а в методе Add_Element при помощи dynamic_cast  определеять конкретно какого класса объект был ему передан и инициализировать его. 

И при добавлении нового класса каждый раз переписывать Add_Element smile
Я же показал выше код, который относительно усешно решает такую задачу. При этом  Parser понтия не имеет с полях, которые он инициализирует





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Anikmar
Дата 1.2.2007, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(Vyacheslav @  1.2.2007,  18:42 Найти цитируемый пост)
И при добавлении нового класса каждый раз переписывать Add_Element 
Я же показал выше код, который относительно усешно решает такую задачу. При этом  Parser понтия не имеет с полях, которые он инициализирует


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

При написании порожденного класса либо надо зарегистрировать методы установки либо переопределить виртуальные - все зависит от конкретного применения.

Ваш метод более универсален, мой метод проще для понимания.
PM MAIL ICQ   Вверх
knut
Дата 1.2.2007, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 7.2.2006

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



если при создание обектаов  (наследников)  полья классов иницализуются одинакого (для каждого класса)то то почему не иницализовать иx прям в конструкторе  а потом при вызове Аdd_Elemet() получить иx и записать в фаил.
P.S по моему это в полне логичная организаьцыя smile ато и я запутолся и вас запуталsmile 


--------------------
Цитата

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

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

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

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

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


 




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


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

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