LINUX.ORG.RU

Срочно нужна помощь с указателем на функцию-член (С++)


0

0

Проблема в слежующем:
class Object
{
	...
	void (*pfunc)(Object*);
	...
}
class Mobject
{
	void (*Myfunc)(Object*);
}
Mobject::Mobject()
{
	void (Mobject::*Mufunc)(Object*) = &Mobject::bfunc;
	Object *p = new Object()
	p->pFunc = &Myfunc;
}
и при обращении к pFunc - валится ?? что делать или как делать

anonymous

эээ, поясни плиз, что именно ты хочешь сделать --- скажу как :)

anonymous
()

Сють в следующем: Есть класс А елементом которого является массив класса В? оба класа не пересекаются, в классе В есть функция которая время от времени вызывается из нити органнизованной в классе В, все работает в пределах класса или поражденного от него, так вот необходимо что-бы все елементы массива В обращались только к одной функции из класса А ((( как зделать не знаю, закидывать к ним void* parent; а потом обращатся ((А*)parent)->myfunction().., чего-то мне не нравиться, да и смысл в том? что-бы классы друг друга не знали,

anonymous
()

class A;

class B {
        typedef void (A::* pa_mem) ();
  public:
        void fb(A* pa, pa_mem member) {(pa->*member)();}
};

class A {
  public:
        B pb[10];
        void fa(void);
        void testfb(void) {pb[0].fb(this, &A::fa);}
};

так годится? или не это нужно было? если не это, давай еще раз
объясняй :)

HTH

anonymous
()

)))), так все и дело в том, что В об А ничего незнает - А может быть любой класс, и мне нужно в В описать вункцию (скорее всего указатель) так? что-бы ее можно было переназначить из класса А, класс А знает о классе В и он НЕ является наследником В в каком нибудь колене ))

anonymous
()

Полностью информацию об Mobject скрыть от Object не удастся, так как вызов
метода через указатель всегда связан с конкретным существующим объектом.
Это не относится только к статическим методам, а тебе, как видно, нужен
нестатический.

Чтобы гибкость системы была максимальной, попробуй использовать концепцию
функтора. Чтобы было совсем красиво, я сделаю немножко подлиннее, чем можно
было бы. Значит, пусть в файле functors.h имеются классы:

class functor {
public:
   functor(afunc * f) : ff(f) {}
   void operator()(Object * o) { ff->call(o); }
private:
   auto_ptr<afunc> ff;
};

class afunc {
public:
   virtual void call(Object * o)=0;
   static afunc * make(Mobject*);
};

В файле object.h:

#include "functors.h"

class Object { 
public:
   Object(functor f) : ff(f) { /* ... */ }

   // вызов будет происходить так:
   void my() {
      Object * oo;
      // ...
      ff(oo);
   }

private:
   functor ff;
};

А в файле functors.cc реализация:

#include "Mobject.h"
#include "functors.h"

class afunc_A : public afunc {
public:
   afunc_A(Mobject * o) : obj(o) {}
   virtual void call(Object * o) { obj->member_of_A(o); }
private:
   Mobject * obj;
};

afunc * afunc::make(Mobject * o) 
{
   return new afunc_A(o);
}

А твой конструктор примет вид:

Mobject::Mobject()
{
   Object *p = new Object(functor(afunc::make(this)));
}

Все! Мы получили именно то что ты хотел...
Object практически ничего не знает о Mobject, кроме того минимума... 
Всегда можно перейти от Mobject к любому другому классу...
Что ты обо всем этом думаешь?

JekLove
()

2JekLove. Красиво, ничего не скажешь, только тому, кто вопрос задал, я бы посоветовал более простые пути искать для решения задач... не склоняться к примитивизму, но добиваться изящной простоты ;-)) тут налицо нарушение основных принципов проектирования... ибо класс B, являющийся членом класса А и вызывающий функцию этого самого класса А - аномалия.

Готов выслушать противоположные мнения.

Еще раз для JekLove. Здорово у тебя получилось.

С уважением, Солнышко

anonymous
()

Действительно красиво, но проблема решилась сама собой уменя появилась возможность создать оди базовый класс для обоих, огромное спасибо за участие, а по поводу предложенного решения то виртуозно, я так в винде спрыгивал с проблемы но при помощи asm, а суть таже, в линухе АСМ боюсь пользовать

anonymous
()

Мне бы хотелось уточнить самую суть происходящего. Вообще, то, что я показал, совсем просто... Самый важный момент - то, что обычный (нестататический) метод всегда привязан к конкретному объекту, то есть все равно что переменная-член... ну нельзя его вызвать просто так... этот указатель - просто смещение в байтах от начала класса. Вот. Еще раз повторюсь: информацию от вызывающего класса скрыть средствами С++ невозможно... разве что сделать такую гнусь: typedef void (*func)(Object*); Object obj; func f = (func)((char*)&obj+(char*)&Object::method)); А уж это выглядить просто грязно... омерзительно. Даже самому противно стало :) Еще мне не очень понятны причины, по которым класс B, являющийся членом класса А и вызывающий функцию этого самого класса А - аномалия. (цитата из мессаги Солнышка :) Почему ты считаешь, что такая обратная связь есть нарушение принципов проектирования? Я не считаю себя все знающим, так что мой вопрос ни в коей мере не является провокационным :)) Теперь вопрос к первому докладчику :) Тебе не кажется, что смешивать С++ с чем-нибудь (а тем более с асмой) - не есть хорошая идея? У меня почему-то такое стойкое ощущение имеется. Это все равно что смешивать персиковый компот с томатным соком :) Языковые трудности обычно обходятся более тщательным проектированием... асм нужен когда нужна максимальная скорость... isn't it?

JekLove
()

2JekLove. Я тоже не претендую на звание "всезнайки" ;-)) Просто всегда стараюсь в работе добиваться того, чтобы схема функциональных связей объектов не была сложной и запутанной.
Подобные сложности в иерархии классов и объектов приводят к сложностям в отладке, к возможному понижению надежности конструкции в целом и к снижению уровня "понимаемости" кода (это чисто субъективное мнение, я считаю - программа должна писаться так, чтобы быть "чистой" и "понятной" не только самому разработчику, но и другим, возможно сторонним людям).
Что касается использования asm для получения скрытой в объекте информации, то мое понимание таково: метод это эффективный, но недозволенный. Ибо это - прямое нарушение идеологии ООП.
Если кто-то готов поспорить - слушаю самым внимательным образом.

С уважением, Солнышко

anonymous
()

Согласен, что асм путать с с++ грубо , но когда очень надо, то я думаю все способы уместны ))

anonymous
()
28 октября 2002 г.

Объяви все используемые функции-члены static

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.