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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Трюк, возможно ли это? 
:(
    Опции темы
vinter
Дата 6.9.2008, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



Цитата(vaddsm @  6.9.2008,  17:57 Найти цитируемый пост)
Конструктор явно не задействован:

но задействован ;)

Цитата(vaddsm @  6.9.2008,  17:57 Найти цитируемый пост)
что нет ничего невозможного

попробуй на досуге задницей через форточку вылезти, стандартную форточку совестких домов

Цитата(vaddsm @  6.9.2008,  17:57 Найти цитируемый пост)
 Может все же можно пойти на хитрость?

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


--------------------
Мой блог
PM MAIL WWW   Вверх
vaddsm
Дата 6.9.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

Например, установив служебное слово virtual перед методом void __fastcall Method1();, мы указываем компилятору, что необходимо сделать данную функцию виртуальной и внести ее в VMT, DYNAMIC соответственно в DMT. У меня реализовано некоторое подобие VMT, но методы заносятся туда не на стадии компиляции а уже в рантайме. Собственно, для функций, которые реализуют с методами класса, нужные мне действия я пишу удобный интерфейс.

Чтобы, это было настоль же лаконично и просто, как поставит фразу virtual в начале метода. Не нагружать пользователя сложными конструкциями, которые нужно прописывать в различные области класса (в том числе в конструктор).

Например так как я писал:

Код

class C1 
{

protected:

SOME_STAFF_BEGIN

 DO_SOME_WORK(…)
 DO_SOME_WORK(…)
 DO_SOME_WORK(…)

SOME_STAFF_END


};


Но, пока не придумал варианта проще чем, еще и в конструктор вносить  
Код

SOME_STAFF_INIT.



P.S Предлагаю пока откинуть универсальные кроссплатформенные методы, если таких нет для решения данной задачи, и сосредоточить внимание на средах BCB и VS. Любые конструктивные идеи приветствуются!



Это сообщение отредактировал(а) vaddsm - 6.9.2008, 18:24
PM MAIL   Вверх
mes
Дата 6.9.2008, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(vaddsm @  6.9.2008,  14:16 Найти цитируемый пост)
Ты это к чему сказал то? Разве из моего сообщения следует, что я хочу создать ОБЪЕКТ не задействовав в этом мероприятии его КОНСТРУКТОР. Прошу перед тем, как что либо  писать, внимательно вникать в суть поставленной задачи. 


Цитата(vaddsm @  6.9.2008,  03:10 Найти цитируемый пост)
Мне необходимо добиться того, чтобы конструктор класса TClass1 не был задействован, но при инициализации экземпляра класса TClass1 выполнился код (функция) с параметром.


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



Цитата(vaddsm @  6.9.2008,  14:16 Найти цитируемый пост)
Например в VCL есть подобная реализация, таблица регистрирующая функции-обработчики оконных сообщений. 

Вы наверно будете сильно удивлены, но в приведенном примере ни одна строчка не выполняется при инициализации. В том числе и метод Dispatch (). 

Цитата(vaddsm @  6.9.2008,  16:57 Найти цитируемый пост)
Конструктор явно не задействован:
Код

  TClass1(){};

А код всеже выполняется! (MessageBox)

Потому что задействован!!!  конструктор по умолчанию  smile 

Цитата(vaddsm @  6.9.2008,  16:57 Найти цитируемый пост)
Может все же можно пойти на хитрость?

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


Цитата(Fin @  6.9.2008,  17:07 Найти цитируемый пост)
Вопрос остается в силе, Для чего данное действо вообше нужно? 


Цитата(vaddsm @  6.9.2008,  17:32 Найти цитируемый пост)

Есть набор функций, которые реализуют некоторое преобразование полей класса, скажем изменяют поведение некоторых методов этого класса...
Чтобы, это было настоль же лаконично и просто, как поставит фразу virtual в начале метода. Не нагружать пользователя сложными конструкциями, которые нужно прописывать в различные области класса (в том числе в конструктор).


Что скрыто тут ? :
Цитата(vaddsm @  6.9.2008,  17:32 Найти цитируемый пост)
SOME_STAFF_BEGIN
 DO_SOME_WORK(…)
 DO_SOME_WORK(…)
 DO_SOME_WORK(…)
SOME_STAFF_END


Цитата(vaddsm)

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

Код

SOME_STAFF_INIT.



Ну a если добавить в Ваш дефайн  строчку добавляюшая в нужный класс  регистратор(или другой вспомогательный объект) с конструктором по умолчанию ?

Это сообщение отредактировал(а) mes - 6.9.2008, 18:44


--------------------
PM MAIL WWW   Вверх
vaddsm
Дата 6.9.2008, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



mes

Цитата

Цитата(vaddsm @  6.9.2008,  14:16 Найти цитируемый пост)
Например в VCL есть подобная реализация, таблица регистрирующая функции-обработчики оконных сообщений. 

Вы наверно будете сильно удивлены, но в приведенном примере ни одна строчка не выполняется при инициализации. В том числе и метод Dispatch ().



Вы наверно, будете еще больше удивлены обнаружив, в том посте, откуда вы взяли эти строчки, следующие слова:

Проблема, в том что, метод Dispatch применяется в самом классе в нужном месте и в нужное время. В моем случае я делаю произвольную надстройку на любой класс и он, о моем подобии Dispatch ни сном не духом, по этому приходится прописывать вызов этого метода еще и в конструкторе…
 
Мне даже обидно как-то, ведь я сам написал об этом подробно.

 
Цитата

Цитата(vaddsm @  6.9.2008,  16:57 Найти цитируемый пост)
Конструктор явно не задействован:
Код

  TClass1(){};

А код всеже выполняется! (MessageBox)

Потому что задействован!!!  конструктор по умолчанию  smile



Ок, здесь действительно мои слова можно было понять не правильно. Сказав “Конструктор явно не задействован” я имел ввиду, что мы руками не прописываем сюда TClass1(){/*Ничего*/};. Хотя, компилятор, еще да точки /*Ничего*/ помещает инструкции вызывающие конструктор TClass2. А в котором, уже в свою очередь, следует код вызывающий MessageBox.

PM MAIL   Вверх
mes
Дата 6.9.2008, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(vaddsm @  6.9.2008,  18:47 Найти цитируемый пост)
Мне даже обидно как-то, ведь я сам написал об этом подробно.


Цитата(vaddsm @  6.9.2008,  18:47 Найти цитируемый пост)
 В моем случае я делаю произвольную надстройку на любой класс и он, о моем подобии Dispatch ни сном не духом, по этому приходится прописывать вызов этого метода еще и в конструкторе…

Я расценил эти слова, что в Вашем коде надо прописывать вручную, а в VCL это делается автоматом. Но в примере не нашел ничего подобного. smile 
тем более что перед примером шла строчка :
Цитата(vaddsm @  6.9.2008,  14:16 Найти цитируемый пост)

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

тут по контексту возникает смысл, что регистрация происходит в момент инициализации..

Если Вы имели ввиду виртуальность Dispatch,  (инициализацию указателя на VMT) то причем тут вобще VCL ?



Это сообщение отредактировал(а) mes - 6.9.2008, 18:57


--------------------
PM MAIL WWW   Вверх
vaddsm
Дата 6.9.2008, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



mes, все похоже, что Вы меня поняли. Искренне спаибо! 


Цитата

Ну a если добавить в Ваш дефайн  строчку добавляюшая в нужный класс  регистратор(или другой вспомогательный объект) с конструктором по умолчанию ?


У меня так:
Код


#define MSL_TABLE_BEGIN TMethodSpliceInterface MSL;                                         \
void __fastcall MSL_INIT()                                                                  \
{
#define REPLACE_INCURINST_METHOD(lpOriginlMethod, CallType, lpDstMethod, lpInheritedMethod) \
MSL.ReplaceMethod(CallType, SPLICE_CURRENT_INST,                                  \
&lpOriginlMethod, &lpDstMethod, &lpInheritedMethod);
#define REPLACE_INALLINST_METHOD(lpOriginlMethod, CallType, lpDstMethod, lpInheritedMethod) \
MSL.ReplaceMethod(CallType, SPLICE_ALL,                                           \
&lpOriginlMethod, &lpDstMethod, &lpInheritedMethod);
#define MSL_TABLE_END                                                                       \
}

#define MSL_TABLE_INIT MSL_INIT();



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

P.S. Если после этого поста остаются еще вопросы, прошу задовать.


Это сообщение отредактировал(а) vaddsm - 6.9.2008, 19:46
PM MAIL   Вверх
mes
Дата 6.9.2008, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Вам необходим this для вашей таблицы либо косвенно (как у вас в примере), либо прямо.
"Автоматически"при инициализации его можно получить только в конструкторе, того объекта,
методы которого вам нужно делегировать.
ИМХО, решить задачу, не затрагивая конструктора, нереально. 


--------------------
PM MAIL WWW   Вверх
vaddsm
  Дата 6.9.2008, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

P.S Предлагаю пока откинуть универсальные кроссплатформенные методы, если таких нет для решения данной задачи, и сосредоточить внимание на средах BCB и VS. Любые конструктивные идеи приветствуются!


 smile Ну так, что в средах BCB и VS, подобное не реализуемо? smile Прошу поднять правую руку, всех кто уверен что это так ).
PM MAIL   Вверх
mes
Дата 6.9.2008, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Мне кажется Вы не туда акцент поставили в вопросе.
В данном исполнении у Вас, основная загвоздка на мой взгляд не в использовании конструктора,
а в том , что пользователь может забыть добавить нужную строчку, для инициализации.
Чтоб избежать подобного, надо научить компилятор сообщать об этом.
Поэтому предлагаю реализовать описание таблицы внутри вспомогательного класса, для инициалиции которого требуется this основного.
Тогда даже если пользователь добавит несколько конструкторов к основному классу, то компилятор не позволит не проинициализировать таблицу.  smile 


--------------------
PM MAIL WWW   Вверх
vaddsm
  Дата 6.9.2008, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Мне кажется Вы не туда акцент поставили в вопросе.
В данном исполнении у Вас, основная загвоздка на мой взгляд не в использовании конструктора,
а в том , что пользователь может забыть добавить нужную строчку, для инициализации.


Абсолютно, точно. Можно, конечно и ваш вариант, если я его правильно понял.

Давайте на практике рассмотрим (простенький пример), того, что именно Вы имеете ввиду.

Предположим дан вспомогательный класс Tmsl, у него есть метод void __fastcall dosomestuff(LPVOID PointerTo_PrimaryClass_Member); Вызывая данный метод я произвожу действия над членами основного класса. И допустим, есть основной класс, назовем его TPrimaryClass. Из данных условий, как ваша идея должна быть выражена в коде?



PM MAIL   Вверх
Lazin
Дата 6.9.2008, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



тем кто понял суть вопроса, расскажите в 2х словах...

Цитата(vaddsm @  6.9.2008,  15:01 Найти цитируемый пост)
Предлагаю рассмотреть, такой пример: В классе есть метод, необходимо его выполнить сразу после инициализации объекта в памяти, при этом конструктор класса должен оставаться незадействованным в вызове этого метода.

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

сразу напрашиваются два решения:
  • фабрика объектов (можно сделать так, что-бы экземпляр класса можно было создать только с помощью фабрики)
  • умный указатель (можно сделать так, что-бы с объектом можно было работать только через определенный smart-pointer)



Цитата(vaddsm @  6.9.2008,  15:36 Найти цитируемый пост)
class C1 
{
protected:
SOME_STAFF_BEGIN
 DO_SOME_WORK(…)
 DO_SOME_WORK(…)
 DO_SOME_WORK(…)
SOME_STAFF_END
};

там где я работаю, за такой код могут и уволить... smile 

Это сообщение отредактировал(а) Lazin - 6.9.2008, 23:11
PM MAIL Skype GTalk   Вверх
mes
Дата 6.9.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Lazin @  6.9.2008,  23:09 Найти цитируемый пост)
тем кто понял суть вопроса, расскажите в 2х словах...

задача:  делегировать произвольные методы одного объекта объекту обработчику.
Само делегирование проблем не вызывает. Вопрос как красиво оформить, чтоб клиент, мог интуитивно использовать
библиотеку, и компилятор предупредил бы в случае ошибки/упущения.

Добавлено @ 23:36
Цитата(vaddsm @  6.9.2008,  23:02 Найти цитируемый пост)
Предположим дан вспомогательный класс Tmsl, у него есть метод void __fastcall dosomestuff(LPVOID PointerTo_PrimaryClass_Member); Вызывая данный метод я произвожу действия над членами основного класса. И допустим, есть основной класс, назовем его TPrimaryClass. Из данных условий, как ваша идея должна быть выражена в коде?


Не до конца понял, что имели тут ввиду.
Как насчет такого? использование виртуальности для реализации callback'a
Код


class Imsl
{
  public:
     void SomeStuff () {doSomeStuff (); }
  protected:     
      virtual void doSomeStuff ()   =0;
};

class Class1
{
      Tmsl : public Imsl
     {
        public:
          Tmsl (Class1 *p) : p_obj (p) {}
        protected:     
              void doSomeStuff ()  { p_obj ->doSomeStuff(); }
        private:
          Class1 *p_obj;
     } m_msl;

    public:
 
        Class1 () : m_msl(this) {} 
 
  protected:     
        void doSomeStuff ()  {... }
   
};

 


Это сообщение отредактировал(а) mes - 6.9.2008, 23:37


--------------------
PM MAIL WWW   Вверх
vaddsm
Дата 6.9.2008, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

там где я работаю, за такой код могут и уволить...


Возможно, оффтоп и все же, что не так в примере то? (в двух словах)

Цитата

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


Есть класс, совершенно любой, со своим набором методов и свойств. И у нас есть универсальный инструмент (другой класс), совершающий действия над методами любого класса. Для этого инструмента надо написать удобный интерфейс. 

Пример, есть класс над которым совершается действо:


Код

Class ExampleCalss
{

  protected:

   int any_var1;
   int any_var2;
   int any_var3;

  public:

  void __fastcall Method1();
  void __fastcall Method2();
  void __fastcall Method3();

  __fastcall ExampleCalss();
  __fastcall ~ExampleCalss();

};


Применительно к нему, код выполняющий интерфейс для “Инструмента”, выглядит так:


Код

Class ExampleCalss
{

  protected:

   int any_var1;
   int any_var2;
   int any_var3;

  public:

  void __fastcall Method1();
  void __fastcall Method2();
  void __fastcall Method3();

  TOOL_TABLE_BEGIN
  
  DO_ACTION(Method1, Method2)
  DO_ACTION(Method3, Method2)
  TOOL_TABLE_END


  __fastcall ExampleCalss();
  __fastcall ~ExampleCalss();

};



Все замечательно, красиво, удобно, но приходится писать еще в конструктор:


Код

__fastcall ExampleCalss::ExampleCalss()
{
 TOOL_TABLE_INIT
};


А ооочень не хотелось бы.

Пример дефайнов для TOOL_TABLE я выложил выше.

Добавлено @ 23:46
Цитата

задача:  делегировать произвольные методы одного объекта объекту обработчику.
Само делегирование проблем не вызывает. 



Ну, ну нет не такая задача.

Цитата

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


Вопрос, верный!


Это сообщение отредактировал(а) vaddsm - 6.9.2008, 23:49
PM MAIL   Вверх
Lazin
Дата 6.9.2008, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



ради бога
Код

template<class Derived>
class MyClass : public Derivde
{
public:
    MyClass()
    {
        //вызывается после создания Derived
        std::cout << "initialization done" << std::endl;
    }
    void some_method(int param)
    {    
        some_method_impl(param); 
    }
};

class impl_
{
    void some_method_impl(int param)
    {
        std::cout << "Implementation" << std::endl;
    }
};


typedef MyClass<impl_> MyImpl;

MyImpl instanse;
instanse.some_method(111);

вот вам и вызов сразу после инициализации)) 

Это сообщение отредактировал(а) Lazin - 7.9.2008, 00:09
PM MAIL Skype GTalk   Вверх
vaddsm
Дата 6.9.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Хотел вам mes + поставить за огромное стремление помочь, но не дают пока это сделать, говорят постов мало. 

mes, пока не то. По последнему посту есть вопросы?


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.2102 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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