On Apr 2, 12:05 pm, Praetorian <ashish.sadanan...@gmail.com> wrote:
I
don't want ClassA'smemberfunctionto call ClassB'sfunctiondirectly
because ClassA can be used in 2 ways, one of which is a case in which
it does not create an instance of ClassB; hence by passing afunction
pointerI can handle that case easily.
...
classClassA {
public:
typedef BOOL (ClassA::*FPAbortFlag)(void);
...
m_fpAbort = (FPAbortFlag)(&(ClassB::GetFlagX));
You can not do what you are trying to do the way you are trying to do
it. Your code compiles with the explicit cast but will not necessarily
run correctly, and the reason you need an explicit cast to get it to
compile is because the types are not compatible. You have declared
FPAbortFlag as apointerto amemberfunctionin ClassA. That is a
distinctly different type than apointerto amemberfunctionin
ClassB. Your FPAbortFlag can not store pointers to any other functions
besides ones that are members of ClassA -- meaning it can't store apointerto a ClassBfunction, and it can't store apointerto a non-memberfunctioneither (which, if I understand you correctly, is
something you'll eventually want to do if ClassA has no ClassB
instance).
You have a couple of different options. One simple one is:
typedef BOOL (ClassB::*FPAbortFlag) (void);
Note that it is apointerto a ClassBmember. And then, in your ClassA
logic:
if (m_fpAbort && m_pClassB)
m_pClassB->*m_fpAbort();
else
do_the_other_thing();
A second option is to make your ClassB inherit some baseclassthat
describes the interface you are expecting it to have, and change your
definition of ClassA a little to say that it will *always* have an
instance of whatever baseclassClassB inherits from (i.e. don't let
it sometimes be used with one, and sometimes be used without one). For
example:
=== BEGIN EXAMPLE ===
classFPAbortHandler {
public:
virtual BOOL FPAbort () = 0;
};
classClassB : public FPAbortHandler {
public:
BOOL FPAbort () { }
};
classClassA {
public:
void DoSomething () {
if (m_fpAbort) m_fpAbort->FPAbort();
}
private:
FPAbortHandler *m_fpAbort;
};
=== END EXAMPLE ===
In that case, ClassA could handle anything that implemented the
FPAbortHandler interface, which includes ClassB, or any other object
that you may want to define. This is the way I would personally do it,
because it is a good balance between simplicity and flexibility. If
you need to use thepointer-to-memberfunctionto give options of whatmemberfunctionto call, it can be a:
typedef BOOL (FPAbortHandler::*FPAbortFlag) (void);
And can point to any FPAbortHandler members.
A third option is to make your ClassA a baseclassfor some special
derived classes, leaving the details that are different to the derived
classes. If your ClassA can be used in a few different ways, it is
also appropriate to use two different classes with the common stuff in
ClassA. For example:
=== BEGIN EXAMPLE ===
classClassA {
...
public:
void DoSomething () {
...
DoIt();
...
}
protected:
virtual void DoIt () = 0;
...
};
classClassAWithB : public ClassA {
...
private:
typedef BOOL (ClassB::*FPAbortFlag)(void);
ClassB *m_pClassB;
FPAbortFlag *m_fpAbort;
protected:
void DoIt () { m_pClassB->*m_fpAbort(); }
...
};
classClassAWithOtherFunction : public ClassA {
...
private:
...
protected:
void DoIt () { ... }
...
};
=== END EXAMPLE ===
In that case, DoIt() takes care of all the differences.
ClassA::DoSomething() does a bunch of stuff and calls DoIt() for
derived-class-specific details. The DoIt()functiondoes the right
thing. Sorry I'm being vague, but it's a general issue.
Using inheritance allows you to access everything via ClassA pointers,
as well:
ClassA *things[2];
things[0] = new ClassAWithB(MyClassB); // or whatever
things[1] = new ClassAWithOtherFunction(...);
Or, of course:
voidfunction(ClassA *a) {
a->DoSomething();
}
And you can pass anything to thatfunction(), and the right thing will
always happen.
Hope that helps, or at least is coherent,
Jason
classes inherit from and have it handle the function pointers. The
pointer (which may be to a member function of an arbitrary class). In
inheriting from a class which is hidden with the DLL itself. Maybe my
very good with C++, so there probably is a better way to do this. What
that can be called by anyone.