Can a single function pointer point to multiple classes member function - c++

Here are the requirements posed by my application. I have a class A, that accepts a function pointer say cFunc, Basically in my implementation of A, I have it call cFunc multiple times.
The cFunc pointer itself should point to different functions depending upon the application. Thus for each application I create a class with the same function definition as cFunc, however I cannot assign the class's member function to this pointer
class A {
typedef double (*Def_CFunc)(std::vector<double>);
A(Def_CFunc _cFunc) { // Some implementation}
// Other Functions
};
class B { double someFunc(std::vector<double> b); };
class C { double someOtherFunc(std::vector<double> a); };
int main () {
B firstObj;
C secondObj;
// Depending upon the situation, I want to select class B or C
double (*funcPointer)(std::vector<double>) = firstObj.someFunc; // Error in this line of code
A finalObj(funcPointer);
}
So how do I make it such that any class with a member function of the given format can be used to initialize the class A?

I'm not sure what exactly your requirements are, but it looks like you want an interface (or abstract base class in C++ lingo).
If both B and C inherit from a common base class, you can pass a pointer to this base class and invoke functions on it:
class I { virtual double func(std::vector<double> a) = 0; }
class B : public I { double func(std::vector<double> a); };
class C : public I { double func(std::vector<double> a); };
You can pass an I* pointer to A and just use i->func.

Pointer to member function has different syntax than pointer to ordinary function and can only point to a method of one given class. To be able to point to methods in different classes use boost::function or if C++11 is available use std::function. These can hold any method or function of a given signature.

What you need is std::function together with either std::bind or lambda expressions (or the Boost equivalent of the first two), because member function pointers don't allow you to do that.

You can do it using std::bind + std::function. Lets write some template class wrapper, that takes any static type as input. Then use this wrapper in free function switch_obj. Usage is very simple.
typedef std::function<double(std::vector<double>)> my_foo;
template<class C>
struct switcher
{
static my_foo convert(C* obj)
{
return my_foo( std::bind(&C::someFunc,obj,std::placeholders::_1) );
}
};
template<class T>
my_foo switch_obj(T* obj)
{
return switcher<T>::convert(obj);
}
void main()
{
B firstObj;
C secondObj;
auto f = switch_obj(&firstObj);
A a(f);
}

Related

Passing Member Function Pointer into a Template

First of all sorry for the title being confusing. Here's my OOP setup. I have base class Base, and two pure virtual functions add and multi. Then I have derived classes D1 and D2 and I implement the add and multi functions. I want to have a template function, that can have the flexibility that can switch between D1 D2 and calling add or multi functions. I googled around and someone people saying I should use function pointers but some others say it does not work with pure virtual functions.
class Base
{ double data; //data member
Base(double d):data(d){};
virtual double add() = 0;
virtual double multi() = 0;
}
class D1::public Base
{ D1(double d): Base(d) {}; //calling base class constructor
double add() {return data+1;} ;
double multi() {return data*2;} ;
}
class D2::public Base
{ D2(double d): Base(d) {}; //calling base class constructor
double add() {return data+3;} ;
double multi() {return data*4;} ;
}
//now I want to have a template function that give me flexibility to construct D1 or D2 and calling add or multi.
template <typename T, typename F>
void testFun(double num)
{ T tmp(num); //create object either D1 or D2;
cout << T->F() << endl; //calling either add or multi;
}
int main()
{ testFun<D1, D1.add()>(double x = 5);
//i know passing in D1.add() is wrong i don't know how to fix, hopefully you know what I am trying to achieve
return 0;}
Any help will be appreciated. Thank you guys.
There's nothing about virtual member functions that makes pointers to member functions not work. You can invoke a pointer to a pure virtual function if the object being invoked on is a pointer/reference to an object that has an actual implementation.
It looks like you're getting tripped up on the syntax of exactly how to pass a pointer-to-member-function in the first place.
Also note that virtual dispatch wouldn't even be used here since the type of object being used is known at compile time.
template <typename T>
void testFun(double num, double (T::*fn)())
{
T tmp(num);
std::cout << (tmp.*fn)() << std::endl;
}
Here, fn is a pointer to a member function of T that accepts no arguments and returns a double value. You can invoke it like so:
testFun<D1>(5, &D1::add);
Note some other errors with the example code you've given:
You specify base types with :: when you should use :. For example: class D1 : public Base.
You use class but never specify an access modifier, which means all members are implicitly private. For the purposes of the demo, changing them to struct (which defaults to public access) fixes this.
You need a semicolon after a class/struct definition.
Here is a demo of the working code.
Just for the sake of completeness, here is a demo showing that you can use a pointer to a pure-virtual member function to invoke on a reference/pointer to a derived type. The code has to be adjusted to use a D1 or D2 object through a reference of Base for the dispatch to be dynamic. This example looks like:
template <typename T>
void testFun(double num, double (Base::*fn)())
{
T tmpConcrete(num);
Base & tmp = tmpConcrete;
std::cout << (tmp.*fn)() << std::endl;
}
int main() {
testFun<D1>(5, &Base::add);
}
(Of course, here it's a bit silly to use a pointer to a Base member when the generic code knows what T is, but it proves the point that it's possible.)

Derived class doesn't override a virtual function with a different signature

I have a derived class where I want one of the functions to override its version in the base class, but have a different signature.
Simple example:
#include "stdio.h"
bool use_foo = false;
class Foo {
public:
virtual int func(double x) { printf ("%f in Foo!\n", x); }
};
class Bar : public Foo {
public:
int func(short x) { printf ("%d in Bar!\n", x); }
};
int main () {
Foo* A;
if (use_foo)
A = new Foo;
else
A = new Bar;
A->func(2);
return 0;
}
The above code would call the base class copy even though A was allocated as the derived class:
> g++ test.cpp -o test -O3 && ./test
2.000000 in Foo!
Because (as far as my understanding goes) the argument can be converted to match the base class signature, and the derived class doesn't override it because of this difference (but wouldn't it hide it in that case?). If I change the base class function to have short as argument as well, the derived class does manage to override it.
Is there a simple way to convince the call to use the correct function based on the pointer? I could add another function like this:
class Bar : public Foo {
public:
int func2(short x) { printf ("%d in Bar!\n", x); }
int func(double x) { func2(x); }
};
But then I would convert the arguments all the time (short->double->short), and this function is performance critical. Is there a better way?
These function signatures are not identical:
virtual int func(double x) {...} // base class
int func(short x) {...} // derived class
One uses double parameter, the other uses short. For overriding to occur several conditions must be met. Identical parameter types of the base and derived functions being one of them. Bellow is the excerpt from the "Modern Effective C++" book by Scott Meyers on all the requirements:
• The base class function must be virtual.
• The base and derived
function names must be identical (except in the case of destructors).
• The parameter types of the base and derived functions must be
identical.
• The constness of the base and derived functions must be
identical.
• The return types and exception specifications of the base
and derived functions must be compatible.
Alternatively, make the signatures the same and perform the casting inside a derived function body:
int func(double x) override {
short temp = static_cast<short>(x);
// ...
}
What sense does this make anyway? The reason you use a virtual function is that the caller should only be required to know the base class, and thus only the base-class signature.
In other words, code which has, say, a Foo& or a Foo* or a std::unique_ptr<Foo>, only knows about the double version of your function anyway. It will pass a double when it calls func, because what else should it do?
Perhaps what you really want to do is the subclass implementation of the function to convert the double to a short. Here's an example for that, which also gets rid of the printf in favour of a type-safe C++ stream:
class Bar : public Foo {
public:
int func(double x) { std::cout << static_cast<short>(x) << " in Bar!\n"; }
};
Note that since C++11, you are encouraged to use override to mark overriding functions.
and this function is performance critical.
Should a performance-critical function be virtual at all?
Have you actually measured the speed? Is there a noticeable delay? Or are computers too fast anyway?

Pointer to a class member function

Let's say, I've two classes
class A
{
public:
void foo( /* ............. */ );
};
class B
{
public:
void bar();
};
I want to know, if it's even possible to pass to the foo method a pointer of bar method, store it in A and run bar later from A. I should say, that A won't know, what class bar is a member of!
I'd appreciate much if you show me the syntax or some link with not that complicated description of the topic.
DESCRIPTION
I'm designing an observer pattern for C++. I want to subscribe B to some events of A. e.g. this code should be in an instance of B
// pseudo code
A* observable = new A();
observable->addEventListener ( 'eventTitle' , functionName );
And when eventTitle occurs A calls functionName of B
There is a couple of methods how to call a pointer to member function, hiding it's origin:
Use std::function and std::bind:
class B {
double Sqrt(int what) { return std::sqrt((double)what); }
};
// in A:
std::tr1::function<double (int)> fn;
fn = std::tr1::bind(&B::Sqrt, &operations, std::tr1::placeholders::_1);
fn(3.1415);
Use a functor, which will wrap the pointer to member function and the object, on which it's to be called, togeter. (This is a bit complicated, though, and in principle is just a subset of what std::function does).
Derive B from an abstract interface IFn and pass B as IFn reference to Foo. Foo will know what to call - a virtual Do() function of the interface.
How can A use a member function of B without knowing anything about it? To call it, you need an object, which has to be o type B (or subtype), so A must have this knowledge.
If you make bar() a static function, you can use regular function pointer (void (*)()) or std::function<void ()> (boost::function for older C++) - of which I would strongly recommend the latter.
That won't work unless bar is declared as a static member of B. You should take into account that you would need an instance of B in order to call any non-static methods.
(Check the C++ FAQ chapter on pointer-to-member-functions for a deeper explanation.)
UPDATE: if you want to implement an observer pattern, you can declare an interface (pure abstract class), say Observer, that A knows and use pointer-to-member-functions to map your events to the corresponding Observer methods.
Example:
A observable;
observable.addEventListener ( 'eventTitle' , &B::functionName );
B observer;
observable.registerObserver(&observer);
Use something like:
class A
{
public:
void foo( /* ............. */ );
void SetObs(CObs *pObs)
{
m_pObs = pObs;
}
private:
CObs *m_pObs;
};
class B : public class CObs
{
public:
virtual void bar();
};
class CObs
{
public:
virtual void bar() = 0;
};
And whenever you need bar() function call m_pObs->bar(). Also derive all slasses like B from CObs and override the function bar().

C++ callback to non-static interface method

I have a class A that should call a non-static class method from an interface class B, with signature expressed by, say, the following function pointer:
bool (B::*check)(int) const
Such method would be implemented by a set of classes {C} implementing B, each with multiple methods matching the above signature. I therefore need to bind the callback from A towards B, which in turn would delegate to the chosen method from C.
Edited with some code:
This is a sketch of what I have in mind. Beware that this is only an example of the requirement above, nothing in the organization of the code is mandatory outside, perhaps, class A.
class B {
public:
bool check(int val) const {
// call to a binded method with a given signature (sig) on a Cx class
...
}
};
class C1: public B {
...
// a method implementing the (sig) signature
// another method implementing the (sig) signature
};
class C2: public B {
...
// a method implementing the (sig) signature
// another method implementing the (sig) signature
};
class A {
public:
...
private:
bool result;
int val;
void call_check(B const& b) const {
result = b.check(val);
}
...
};
It that possible in C++? Or equivalently, what would be a solution that allows A to know of class B only?
To my puzzlement, I haven't found a solution around for this very specific need.
Massive Edit
I think I got what you want, based on some heavy type-casting.
Note that I do NOT recommend this technique. Although my example works, I believe there are some big pitfalls here that could really screw things up.
As before, Class A can accept both a method of the proper signature and an object (of type B, or derived from type B, such as your C classes), and call the specified method on the specified object.
Class B does not actually have any methods at all, and only acts as a common base-class for the two classes C1 & C2.
At the bottom is a main that demonstrates how this is used. I left out the implementation of the two SetCallback*** methods, as they're trivial.
class B
{ public: // Has nothing, only serves as base-class for C1 and C2.
};
class C1: public B
{
public: bool DoThis(int x) const { return true; }
};
class C2: public B
{
public: bool DoThat(int x) const { return false; }
};
class A
{
private:
bool (B::*m_check)(int) const;
B* m_Obj;
public:
void SetCallbackFunction(bool (B::*fnc)(int) const)
{ m_check = fnc; }
void SetCallbackObject(B* pB)
{ m_Obj = pB; }
bool InvokeCallback(int val)
{
return (m_Obj->*m_check)(val);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
C1 c;
bool (C1::*func)(int) const;
bool (B::*b_func)(int) const;
func = &C1::DoThis;
b_func = (bool (B::*)(int) const)(func); // Dangerous Typecasting. Use caution!
a.SetCallbackFunction(b_func);
a.SetCallbackObject((B*)(&c)); // A simpler, safer typecast.
a.InvokeCallback(5); // Ends up calling C1::DoThis.
_getch();
return 0;
}
The simplest thing you can do is not to use a member function pointer, but rather a higher order construct like function (either boost or C++11) and register the callbacks with bind (again, boost or C++11).
Pointers-to-member-functions are available, and do exactly what you want. However, just be aware that they are not actually "pointers", but are "pointer-like", since it is possible that proper lookup/calling must go through the "vptr" table(s) associated with a class that may possibly have more-than-one-parent.
In short: Yes, you can have it. If you implement in a template, you do not need to include the target headers (but you would need to implement the target class headers at the point of code expansion). If you implement as a non-template, then you could forward-declare the member functions and get it to work. Or, you could simply include the target class-type headers.
Since multiple target functions are available, yes, at the point of actual binding, you must include the header (you don't need the header if this is a template implementation):
class MyA {
public:
bool foo1(int) const;
bool foo2(int) const;
};
void MyFunc(void) {
bool (MyA::*my_ptr_to_func)(int) const;
my_ptr_to_func = &MyA::foo2;
MyA my_a;
// call it
if((my_a.*my_ptr_to_func)(42))
{
// ...
}
}
[UPDATE], based on your updated code, it seems like you merely want to make "bool B::check(int) const" to be "virtual" in the base class, and override/re-implement that function in the derived "C1" and "C2" classes?
Yes, the virtual function will be called (the implementation in the C1 and C2 classes), even though your pointer was originally to the B::check(int) function. This works, and is exactly why a pointer-to-member-function is not exactly a pointer, but is pointer-like (to permit your call to correctly execute the virtual code in the derived classes).
So, no fear: It will work, just put "virtual" on B::check(int) in the base.
It sounds like you want to use the observer pattern to allow A to hold a vector of function pointers of type bool (B::*check)(int) const.
Classes in {C} could thus register through the observer pattern to A. I don't see why you need an interface, B, explicitly if you use this form of pattern. The interface will be guaranteed by the vector of function pointers requiring the signature of your chosen function pointer.

Mutual return types of member functions (C++)

Is it possible in C++ to have two classes, let's call them A and B, such that A has a member function f that returns an object of class B, and B has a member function g that returns an object of class A?
(The text below is just to show I have "done my homework".)
The problem is just how to write signatures of these functions, when the one in first defined class will have an incomplete return type. Forward declarations don't help here, because objects are returned by value.
Yes, I know all the workarounds (friend global functions, returning by pointer,...), but I would just like to know if the interface as above can be implemented in C++. For the sake of an example, let's say that I am trying to overload operator() on class A to return B, and on class B to return A. Since I am overloading operators, I must return by value (well, unless I want a dynamic allocation hell:), and () must be overloaded as a member function, so I can't use global friends.
Yes, Implement function definitions of class A after you declared class B
class B;
class A
{
B f();
};
class B
{
A g() { A a; return a; }
};
B A::f(){ B b; return b; }
Another possible way to break the dependency loop is to use a template member function, like this:
struct A {
template<typename T> T f() { return T(); }
};
struct B {
A g() { return A(); }
};
int main() {
A a;
B b = a.f<B>();
A a1 = b.g();
return 0;
}
It will work for operator() too, though the call syntax will be rather ugly: a.operator()<B>()