Function Pointers in Classes
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
Firstly, your approach using
void (*display)(char*);
doesn't work as it points to a global orstatic
class member function, not a member function. One way to to do it is the following, assuming the function to be called is alwaysdisplay
:-
Define an interface that contains the function:
class ICallable
{
public:
virtual void display(char *msg) = 0;
};Note the function is a pure
virtual
function. -
Derive the classes that have the function to be called from it:
class A : public ICallable
{
public:
virtual void display(char *msg)
{
// A's impelentation here...
}
}; -
Your pointer now looks like the following:
ICallable *pPointer;
-
The call through the pointer like this:
pPointer->display("Hello world!");
Steve
-
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
What is your requirement? Is it ok if you have static "display" function in class A?
Parag Patel Sr. Software Eng, Varaha Systems
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
What you have done is shown that you want some common operation in
display
method of class A & class B. So, for that here you can take one base class which definedisplay
method. And after that you can inherit your 2 classes A & B from that base class. Both have access ofdisplay
method.
Do not trust a computer... Always check what computer is doing regards, Divyang Mithaiwala Software Engineer
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
I would implement this using Boost.Function[^] and Boost.Bind[^]: In class B, declare display like this:
boost::function<void(char*)> display;
in A, set b.display like this:
B b;
b.display = boost::bind(&A::display, this);in B, call it like this:
if (display) display(whatever string you want to display
The
if (display)
bit is to protect you against the case that nothing's been assigned to B::display. Here's a complete, buildable and runnable example:#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>class B
{
public:
boost::function<void(char*)> display;
void b_test() { if (display) display("test"); }
};class A
{
public:
A() { b.display = boost::bind(&A::display, this, _1); }
void a_test() { b.b_test(); }
void display(char* s) { std::cout << s << std::endl; }
B b;
};int main()
{
A a;
a.a_test();
}Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
I would implement this using Boost.Function[^] and Boost.Bind[^]: In class B, declare display like this:
boost::function<void(char*)> display;
in A, set b.display like this:
B b;
b.display = boost::bind(&A::display, this);in B, call it like this:
if (display) display(whatever string you want to display
The
if (display)
bit is to protect you against the case that nothing's been assigned to B::display. Here's a complete, buildable and runnable example:#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>class B
{
public:
boost::function<void(char*)> display;
void b_test() { if (display) display("test"); }
};class A
{
public:
A() { b.display = boost::bind(&A::display, this, _1); }
void a_test() { b.b_test(); }
void display(char* s) { std::cout << s << std::endl; }
B b;
};int main()
{
A a;
a.a_test();
}Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
I have two independent C++ classes, A and B. I have a non-static public function in class A
void display(char *msg);
I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:
void (*display)(char*);
I have a member of class B in class A, and I am trying to set function pointer as:
B b;
b.display = &A::display;I get the following compiler error:
error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'
I am using Visual Studio 2005. Can any one let me know a proper way of doing this?
ARSALAN MALIK
Why do you want to follow a very
plain-C
path? You know,C++
is a fully featuredOOP
launguage. :)If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
led mike wrote:
The Visual C++ 2008 Feature Pack has implemented TR1[^]
Caught me - I've not got used to having TR1 yet. Also, TR1 doesn't have Boost.Bind in it :-( (or Boost.Lambda, for that matter - even more :-()
led mike wrote:
Although, I would prefer using interfaces as Stephen Hewitt posted.
Fair enough - each approach has its own benefits and drawbacks.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
led mike wrote:
The Visual C++ 2008 Feature Pack has implemented TR1[^]
Caught me - I've not got used to having TR1 yet. Also, TR1 doesn't have Boost.Bind in it :-( (or Boost.Lambda, for that matter - even more :-()
led mike wrote:
Although, I would prefer using interfaces as Stephen Hewitt posted.
Fair enough - each approach has its own benefits and drawbacks.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Stuart Dootson wrote:
Also, TR1 doesn't have Boost.Bind in it Frown (or Boost.Lambda, for that matter - even more Frown)
Well no, there is no Boost namespace but those features are in TR1.
So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Stuart Dootson wrote:
Well, you learn something new every day!
Get in times Stuart! ;P of course I knew nothing about... :rolleyes:
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
Why do you want to follow a very
plain-C
path? You know,C++
is a fully featuredOOP
launguage. :)If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles]You are right, thanks, perhaps I am thinking too much in C :-D
ARSALAN MALIK
-
Firstly, your approach using
void (*display)(char*);
doesn't work as it points to a global orstatic
class member function, not a member function. One way to to do it is the following, assuming the function to be called is alwaysdisplay
:-
Define an interface that contains the function:
class ICallable
{
public:
virtual void display(char *msg) = 0;
};Note the function is a pure
virtual
function. -
Derive the classes that have the function to be called from it:
class A : public ICallable
{
public:
virtual void display(char *msg)
{
// A's impelentation here...
}
}; -
Your pointer now looks like the following:
ICallable *pPointer;
-
The call through the pointer like this:
pPointer->display("Hello world!");
Steve
Thanks a lot for the hint, perhaps I was thinking too much in C :-D
ARSALAN MALIK
-