Инициализация указателя на функцию другого класса
От: golova_  
Дата: 10.09.04 09:32
Оценка:
Суть проблемы такова:
В проекте есть 2 класса CQuery, CTest (соответственно в файлах
query.h и test.h)
Класс CTest использует объект класса CQuery и соответственно в файле
CTest есть строка
 #include "query.h"

Теперь нужные части из классов:
class CQuery
{
public:
        void (*pFunc)(int);
}

class Test : public CFormView
{
private:
        void Func (int);
        void Run ();
}

void Test::Run()
{
        CQuery Query;
        Query.pFunc = Func;
}

На самое последнее присваивание ругается:
cannot convert from 'void (__thiscall Test::*)(int)' to 'void (__cdecl *)(int)'
        There is no context in which this conversion is possible

Если обявить функцию Run как
static void
все работает. Почему?
Мне не нужно static void.
Как сделать без него?

PS
Причем не могу в классе CQuery написать
void (Test::*pFunc)(int);

Потому как нету в этом файле includ'а на test.h, да и не может быть.
Re: Инициализация указателя на функцию другого класса
От: Анатолий Широков СССР  
Дата: 10.09.04 09:40
Оценка:
class CTest;
class CQuery
{
public:
        void (CTest::*pFunc)(int);
        CTest *prt;

        void Notify()
        {
              (ptr->*pFunc)(0);
        }
};
Re: Инициализация указателя на функцию другого класса
От: andrij Украина  
Дата: 10.09.04 09:44
Оценка:
Здравствуйте, golova_, Вы писали:

_> Суть проблемы такова:

_> В проекте есть 2 класса CQuery, CTest (соответственно в файлах
_> query.h и test.h)
_> Класс CTest использует объект класса CQuery и соответственно в файле
_> CTest есть строка
_>
_> #include "query.h"
_>

_> Теперь нужные части из классов:
_>
_>class CQuery
_>{
_>public:
_>        void (*pFunc)(int);
_>}

_>class Test : public CFormView
_>{
_>private:
_>        void Func (int);
_>        void Run ();
_>}


_>void Test::Run()
_>{
_>        CQuery Query;
_>        Query.pFunc = Func;
_>}
_>

_>На самое последнее присваивание ругается:
_>
_>cannot convert from 'void (__thiscall Test::*)(int)' to 'void (__cdecl *)(int)'
_>        There is no context in which this conversion is possible
_>

_>Если обявить функцию Run как
static void
все работает. Почему?

_>Мне не нужно static void.
_>Как сделать без него?

_>PS

_>Причем не могу в классе CQuery написать
_>
void (Test::*pFunc)(int);

_>Потому как нету в этом файле includ'а на test.h, да и не может быть.

К сожалению, можно только через
   void (Test::*pFunc)(int);
   // и 
   Query.pFunc = Test::Func;

А для определиния указателя можно воспользоватся предварительным определением класа
 class Test;
make it simple as possible, but not simpler
Re[2]: Инициализация указателя на функцию другого класса
От: Анатолий Широков СССР  
Дата: 10.09.04 09:57
Оценка:
Query.pFunc = &Test::Func;


Извините
Re: Инициализация указателя на функцию другого класса
От: ssm Россия  
Дата: 10.09.04 10:07
Оценка:
Здравствуйте, golova_, Вы писали:


#include <boost/function.hpp>
#include <boost/bind.hpp>

class CQuery
{
public:
    boost::function<void(int)> pFunc;    
    //boost::function1<void, int> pFunc;    

};

class Test
{
private:
    void Func (int)
    {
    }

    void Run ();
};

void Test::Run()
{
    CQuery Query;
    Query.pFunc = boost::bind(&Test::Func, this, _1);
}
Re[2]: Инициализация указателя на функцию другого класса
От: golova_  
Дата: 10.09.04 20:02
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>
АШ>class CTest;
АШ>class CQuery
АШ>{
АШ>public:
АШ>        void (CTest::*pFunc)(int);
АШ>        CTest *prt;

АШ>        void Notify()
АШ>        {
АШ>              (ptr->*pFunc)(0);
АШ>        }
АШ>};
АШ>


К сожалению из файла query.h (класс CQuery) не видать файл test.h, в test.h есть include "query.h".
Re[2]: Инициализация указателя на функцию другого класса
От: golova_  
Дата: 10.09.04 20:04
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, golova_, Вы писали:



ssm>
ssm>#include <boost/function.hpp>
ssm>#include <boost/bind.hpp>

ssm>class CQuery
ssm>{
ssm>public:
ssm>    boost::function<void(int)> pFunc;    
ssm>    //boost::function1<void, int> pFunc;    

ssm>};

ssm>class Test
ssm>{
ssm>private:
ssm>    void Func (int)
ssm>    {
ssm>    }

ssm>    void Run ();
ssm>};

ssm>void Test::Run()
ssm>{
ssm>    CQuery Query;
ssm>    Query.pFunc = boost::bind(&Test::Func, this, _1);
ssm>}
ssm>


Вот с этого момента можно по-подробнее. Что такое boost/function.hpp?
VC++ 6.0 не находит ничего подобного.
Re[3]: Инициализация указателя на функцию другого класса
От: WolfHound  
Дата: 10.09.04 20:28
Оценка:
Здравствуйте, golova_, Вы писали:

_>Вот с этого момента можно по-подробнее. Что такое boost/function.hpp?

_>VC++ 6.0 не находит ничего подобного.

www.boost.org
тк VC++6 старый и тупой используй такой вариант
//boost::function1<void, int> pFunc;
Хотя в доке для boost::function1 это написано.
... << RSDN@Home 1.1.4 rev. 142 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Инициализация указателя на функцию другого класса
От: Анатолий Широков СССР  
Дата: 11.09.04 11:13
Оценка:
Здравствуйте, golova_, Вы писали:

_>Здравствуйте, Анатолий Широков, Вы писали:


АШ>>
АШ>>class CTest; // forward declaration
АШ>>class CQuery
АШ>>{
АШ>>public:
АШ>>        void (CTest::*pFunc)(int);
АШ>>        CTest *prt;

АШ>>        void Notify()
АШ>>        {
АШ>>              (ptr->*pFunc)(0);
АШ>>        }
АШ>>};
АШ>>


_>К сожалению из файла query.h (класс CQuery) не видать файл test.h, в test.h есть include "query.h".


Так этого и не надо. То что Вам нужно — это forward declaration. И никаких инклудов делать не надо.
Re[4]: Инициализация указателя на функцию другого класса
От: HeavyWave Россия  
Дата: 11.09.04 12:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

boost вообще отсутствует в стандартной поставке MSVC
Re[4]: Инициализация указателя на функцию другого класса
От: golova_  
Дата: 11.09.04 13:10
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Здравствуйте, golova_, Вы писали:


_>>Здравствуйте, Анатолий Широков, Вы писали:


АШ>>>
АШ>>>class CTest; // forward declaration
АШ>>>class CQuery
АШ>>>{
АШ>>>public:
АШ>>>        void (CTest::*pFunc)(int);
АШ>>>        CTest *prt;

АШ>>>        void Notify()
АШ>>>        {
АШ>>>              (ptr->*pFunc)(0);
АШ>>>        }
АШ>>>};
АШ>>>


_>>К сожалению из файла query.h (класс CQuery) не видать файл test.h, в test.h есть include "query.h".


АШ>Так этого и не надо. То что Вам нужно — это forward declaration. И никаких инклудов делать не надо.


Спасибо большое! Заработало.
А вот тут еще вопросик. А что если у меня много таких Test'ов. CTest1, CTest2.... Для всех них, я конечно forward declaration сделаю. А можно ли использовать один и тот же указатель для всех классов? Как бы это удобней сделать?
Re[5]: Инициализация указателя на функцию другого класса
От: Анатолий Широков СССР  
Дата: 11.09.04 18:56
Оценка:
_>Спасибо большое! Заработало.
_>А вот тут еще вопросик. А что если у меня много таких Test'ов. CTest1, CTest2.... Для всех них, я конечно forward declaration сделаю. А можно ли использовать один и тот же указатель для всех классов? Как бы это удобней сделать?

По этому вопросу Вам следует почитать http://www.rsdn.ru/res/book/oo/design_patterns.xml
Автор(ы): Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес
В предлагаемой книге описываются простые и изящные решения типичных задач,
возникающих в объектно-ориентированном проектировании. Паттерны появились
потому, что многие разработчики искали пути повышения гибкости и степени
повторного использования своих программ. Найденные решения воплощены в краткой и
легко применимой на практике форме. Авторы излагают принципы использования
паттернов проектирования и приводят их каталог. Таким образом, книга
одновременно решает две задачи. Во-первых, здесь демонстрируется роль паттернов
в создании архитектуры сложных систем. Во-вторых, применяя содержащиеся в
справочнике паттерны, проектировщик сможет с легкостью разрабатывать собственные
приложения. Издание предназначено как для профессиональных разработчиков, так и
для программистов осваивающих объектно-ориентированное проектирование.
. В частности, Вас будет интересовать паттерн Observe.

Удачи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.