Pointer to a member-function - c++

I would like to do the following:
I have two classes, A and B, and want to bind a function from A to a function from B so that whenever something calls the function in B, the function from A is called.
So basically, this is the scenario:
(important A and B should be independent classes)
This would be class A:
class A {
private:
// some needed variables for "doStuff"
public:
void doStuff(int param1, float *param2);
}
This is class B
class B {
private:
void callTheFunction();
public:
void setTheFunction();
}
And this is how I would like to work with these classes:
B *b = new B();
A *a = new A();
b->setTheFunction(a->doStuff); // obviously not working :(
I've read that this could be achieved with std::function, how would this work? Also, does this have an impact in the performance whenever callTheFunction() is called? In my example, its a audio-callback function which should call the sample-generating function of another class.

Solution based on usage C++11 std::function and std::bind.
#include <functional>
#include <stdlib.h>
#include <iostream>
using functionType = std::function <void (int, float *)>;
class A
{
public:
void doStuff (int param1, float * param2)
{
std::cout << param1 << " " << (param2 ? * param2 : 0.0f) << std::endl;
};
};
class B
{
public:
void callTheFunction ()
{
function (i, f);
};
void setTheFunction (const functionType specificFunction)
{
function = specificFunction;
};
functionType function {};
int i {0};
float * f {nullptr};
};
int main (int argc, char * argv [])
{
using std::placeholders::_1;
using std::placeholders::_2;
A a;
B b;
b.setTheFunction (std::bind (& A::doStuff, & a, _1, _2) );
b.callTheFunction ();
b.i = 42;
b.f = new float {7.0f};
b.callTheFunction ();
delete b.f;
return EXIT_SUCCESS;
}
Compile:
$ g++ func.cpp -std=c++11 -o func
Output:
$ ./func
0 0
42 7

Here's a basic skeleton:
struct B
{
A * a_instance;
void (A::*a_method)(int, float *);
B() : a_instance(nullptr), a_method(nullptr) {}
void callTheFunction(int a, float * b)
{
if (a_instance && a_method)
{
(a_instance->*a_method)(a, b);
}
}
};
Usage:
A a;
B b;
b.a_instance = &a;
b.a_method = &A::doStuff;
b.callTheFunction(10, nullptr);

This i basic a solution
class A {
private:
// some needed variables for "doStuff"
public:
void doStuff(int param1, float *param2)
{
}
};
typedef void (A::*TMethodPtr)(int param1, float *param2);
class B {
private:
TMethodPtr m_pMethod;
A* m_Obj;
void callTheFunction()
{
float f;
(m_Obj->*m_pMethod)(10, &f);
}
public:
void setTheFunction(A* Obj, TMethodPtr pMethod)
{
m_pMethod = pMethod;
m_Obj = Obj;
}
};
void main()
{
B *b = new B();
A *a = new A();
b->setTheFunction(a, A::doStuff); // now work :)
}

Related

Wrong context when calling method

How can I achieve that CoroutineManager::Routine() calls Operator::Worker() ?
Worker() must be called by Routine() in this test scenario.
So the question is whether how C++ handle the context. The Routine() method must not implemented by the Operator class itself.
template <class T>
class CoroutineManager {
private:
T var;
int _a, _b;
public:
CoroutineManager(int a, int b);
T Worker();
void Routine();
};
template <class T>
CoroutineManager<T>::CoroutineManager(int a, int b) {
this->_a = a;
this->_b = b;
}
template <class T>
T CoroutineManager<T>::Worker() {
std::cout << "wrong method" << std::endl;
return var;
}
template <class T>
void CoroutineManager<T>::Routine() {
std::cout << this->Worker() << std::endl;
}
class Operator : public CoroutineManager<double> {
using CoroutineManager::CoroutineManager;
public:
Operator(int a, int b) : CoroutineManager(a,b) {};
virtual double Worker();
};
double Operator::Worker() {
return 3.141;
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(3,4);
op->Routine();
return 0;
}
I've changed the code to fulfill my requirements, but maybe there are exists more straight forward solutions(?). It's only about Worker and Worker2, two different methods in two objects which can be called by the derived Routine method without the boundaries of inheritance context:
// MARK: -
template <typename T, typename V>
class CoroutineManager {
private:
V _a, _b;
V (T::*workerPtr)();
T *cm;
public:
CoroutineManager(V a, V b) {
this->_a = a;
this->_b = b;
}
void Routine() {
std::cout << (*cm.*workerPtr)() << std::endl;
}
void SetWorker(T *cm, V (T::*ptr)()) {
this->workerPtr = ptr;
this->cm = cm;
}
V getA() {
return this->_a;
}
V getB() {
return this->_b;
}
};
// MARK: -
class Operator : public CoroutineManager<Operator,int> {
private:
int xx;
public:
Operator(int a, int b) : CoroutineManager(a,b) {
this->xx = a*2 + b*2;
};
int Worker();
};
int Operator::Worker() {
return getA() * getB() + this->xx;
}
// MARK: -
class Operator2 : public CoroutineManager<Operator2,double> {
public:
Operator2(double a, double b) : CoroutineManager(a,b) {};
double Worker2();
};
double Operator2::Worker2() {
return getA() + getB();
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(4,4);
int (Operator::*workerPtr)() = &Operator::Worker;
op->SetWorker(op, workerPtr);
op->Routine();
Operator2 *op2 = new Operator2(3.14,2.78);
double (Operator2::*workerPtr2)() = &Operator2::Worker2;
op2->SetWorker(op2, workerPtr2);
op2->Routine();
return 0;
}
Output:
32
5.92
Program ended with exit code: 0

How can I decrease the number of overloaded functions

I want to know if there is an approach to decrease the number of overloaded function (function edit) in the below code.
class foo
{
public:
foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
void edit(int new_a);
void edit(char new_b);
void edit(float new_c);
void edit(int new_a, char new_b);
void edit(int new_a, float new_c);
void edit(char new_b, float new_c);
void edit(int new_a, char new_b, float new_c);
void info();
private:
int a;
char b;
float c;
};
Here is the implementation of the edit functions :
void foo::edit(int new_a)
{
a = new_a;
}
void foo::edit(char new_b)
{
b = new_b;
}
void foo::edit(float new_c)
{
c = new_c;
}
void foo::edit(int new_a, char new_b)
{
a = new_a;
b = new_b;
}
void foo::edit(int new_a, float new_c)
{
a = new_a;
c = new_c;
}
void foo::edit(char new_b, float new_c)
{
b = new_b;
c = new_c;
}
void foo::edit(int new_a, char new_b, float new_c)
{
a = new_a;
b = new_b;
c = new_c;
}
The edit function will let the user change the parameters of the object as he wishes.
But the thing is that if we add a new parameter we have to add to many overloaded function and I thought there should be a better way.
Here with 3 parameters we need 7 overloaded functions but if we had 4 parameters (a, b, c and d) then we had to develop 14 overloaded function!
That's why I think there should be a better approach.
Thanks.
With variadic and (ab)using std::get<T> on std::tuple, you might do
template <typename... Ts>
void edit(Ts... values)
{
((std::get<Ts&>(std::tie(a, b, c)) = std::get<Ts&>(std::tie(values...))), ...);
}
Demo.
Note: I use std::get<Ts&>(std::tie(values...)) instead of simply values to get error with duplicated input types(edit(42, 42);).
You can avoid the huge number of overloads and still allow the caller to set more than one member in a single expression:
class foo
{
public:
foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
foo& edit(int new_a) { a = new_a; return *this;}
foo& edit(char new_b) { b = new_b; return *this; }
foo& edit(float new_c) { c = new_c; return *this; }
private:
int a;
char b;
float c;
};
int main() {
foo f(1,'c',2.0);
f.edit(42).edit(42.0f).edit('a');
}
Adding a member requires you to write one overload rather than N to support all combinations.
The previous solutions are quite fine, but suppose that all elements have a different type.
A possibility is to still use a variadic template, and in the call to indicate with a string which element must be modified.
This would allow the possibility to have the same type for different elements.
#include <iostream>
#include <string>
class foo {
public:
foo(int _a, char _b, float _c) : a(_a), b(_b), c(_c){};
void edit() {};
template<typename T1, typename... T2>
void edit (const std::string& id, T1 var1, T2... var2) {
if (id == "a") a = var1;
else if (id == "b") b = var1;
else if (id == "c") c = var1;
edit(var2...);
};
void info();
//private:
int a;
char b;
float c;
};
std::ostream& operator<<(std::ostream& os, const foo& obj) {
std::cout << "a = " << obj.a << " b = " << obj.b << " c = " << obj.c;
return os;
}
int main() {
foo example(1, 'a', 2.0);
example.edit("c", 3.0f, "b", 'g', "a", 5);
std::cout << example << std::endl;
}
Given your edit functions that modify a single member:
void edit(int new_a)
{
a = new_a;
}
void edit(char new_b)
{
b = new_b;
}
void edit(float new_c)
{
c = new_c;
}
You can define a single function in C++11 using variadic templates to support multiple parameters in terms of multiple calls with a single parameter:
template< typename FirstType, typename ...OtherTypes >
void edit(FirstType ft, OtherTypes ...ot)
{
edit(ft);
edit(ot...);
}
Using C++17, fold expressions can make this function even simpler.
template< typename ...Types >
void edit(Types ...types)
{
(edit(types), ...);
}
Note: This solution will not try to prevent multiple changes to the same type, such as edit(1, 2, 3);

Avoid the class scope so as to pass a member function as a function pointer

I'll describe my question using the following sample code.
I have class B defined as follows:
class B
{
public:
inline B(){}
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(int (*f)(int x)) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
int(*myfunc)(int);
};
I then define class A as follows:
class A
{
public:
A(int myint) :a{ myint }{ b.setfunction(g); }
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
To me the issue seems to be that the member function g has the signature int A::g(int) rather than int g(int).
Is there a standard way to make the above work? I guess this is quite a general setup, in that we have a class (class B) that contains some sort of member functions that perform some operations, and we have a class (class A) that needs to use a particular member function of class B -- so is it that my design is wrong, and if so whats the best way to express this idea?
You can use std::function:
class B
{
public:
inline B() {}
inline B(std::function<int(int)> f) : myfunc{ f } {}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction([this](int a) {
return g(a);
}
);
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
You could generalize the class B. Instead of keeping a pointer (int(*)(int)), what you really want is any thing that I can call with an int and get back another int. C++11 introduced a type-erased function objection for exactly this reason: std::function<int(int)>:
class B
{
using F = std::function<int(int)>
public:
B(){}
B(F f) : myfunc(std::move(f)) { }
void setfunction(F f) { myfunc = std::move(f); }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
F myfunc;
};
And then you can just provide a general callable into B from A:
A(int myint)
: b([this](int a){ return g(a); })
, a{ myint }
{ }
Use std::function and std::bind
class B
{
public:
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
// ...
A a;
B b(std::bind(&A::g, &a));
Also note that you should initialize the function pointer to some default value (most likely null) and check for it when using, otherwise it's value is undefined.
You could use std::bind to bind the member function A::g.
class B
{
public:
inline B(){}
inline B(std::function<int(int)> f) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction(std::bind(&A::g, this, std::placeholders::_1));
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
Note you need to change the type of functor from function pointer to std::function, which is applicable with std::bind.
LIVE

Dereferencing pointer to functor inside a dereferenced class

I have a functor like this
struct foo
{
int a;
foo(a) : a(a) {}
int operator()(int b) { return a+b; }
};
And a class like this
class bar
{
public:
foo* my_ftor;
bar(foo* my_ftor) : my_ftor(my_ftor) {}
~bar() {}
};
Then suppose a pointer to this class, which contains a pointer to foo.
foo MyFoo(20);
bar MyBar(&MyFoo);
In a function I pass a reference to bar, and I want to run the functor. I got it working the following way:
void AnyFunction(bar* RefToBar)
{
int y;
y = RefToBar->my_ftor->operator()(25);
}
Is there any other "cleaner" way to dereference the functor? Something akin to
y = RefToBar->my_ftor(25);
won't work, sadly...
Any idea? Thank you
Use real references:
class bar {
public:
foo &my_ftor;
bar (foo &f) : my_ftor(f) {}
};
void AnyFunction (bar &reftobar) {
int y = reftobar.my_ftor(25);
}
And call like this
foo myFoo(20);
bar myBar (myFoo);
AnyFunction (myBar);
In the interest of completeness, here is another answer that is more of a modern approach.
class foo {
public:
foo (int i) : a(i) {}
int operator() (int x) const {
return x + a;
}
private:
int a;
};
template <typename F>
void AnyFunction (const F &func) {
int y = func(25);
}
So you can pass in a foo directly:
AnyFunction (foo (20));
Or another kind of function object, like a lambda:
AnyFunction([](int x) -> int {
return x + 20;
});
You could also extend bar to include the following function:
int run_foo (int x) const {
return my_ftor (x);
}
And bind it (#include <functional>):
AnyFunction (std::bind (&bar::run_foo, &myBar, std::placeholders::_1));
Use std::function they are designed to hold functor of any sort.
#include <functional>
#include <iostream>
struct foo
{
int _a;
foo(int a) : _a(a) {}
int operator()(int b) { return _a+b; }
};
class bar
{
public:
std::function<int (int)> _ftor;
bar(std::function<int (int)> my_ftor) : _ftor(my_ftor) {}
~bar() {}
};
void AnyFunction(bar& RefToBar)
{
int y = RefToBar._ftor(25);
std::cout << "Y: " << y << std::endl;
}
int AnotherFunction(int b)
{
return b + 11;
}
int main(int argc, char const *argv[])
{
foo MyFoo(20);
bar MyBar(MyFoo);
bar MyBar_2(AnotherFunction);
bar MyBar_3([](int b) { return b + 56; });
AnyFunction(MyBar);
AnyFunction(MyBar_2);
AnyFunction(MyBar_3);
return 0;
}
http://ideone.com/K3QRRV
y = (*RefToBar->my_ftor)(25);
(better use std::function and don't violate demeter)

How to get rid of the ugly record

class c {
private:
int n[10];
public:
c();
~c();
int operator()(int i) { return n[i];};
};
class cc {
private:
public:
c *mass;
cc();
~cc();
c& operator*() const {return *mass;};
};
int somfunc() {
c *c1 = new c();
cc * cc1 = new cc();
(*cc1->mass)(1);
delete c1;
}
I've got a pointer into class cc to class c.
Is there any way to get rid of record like this:
(*cc1->mass)(1);
and write somethink like that:
cc1->mass(1);
is it impossible?
When I saw the tags "c++" and "operator overloading", my mind alarm turns ON.
C++ operator overloading is complex, and some operators like "()" or "->" make it more difficult.
I suggest, before overloading operators, making either a global function or method with the same purpouse, test it works, and later replace it with the operator.
Global friend function example:
class c {
private:
int n[10];
public:
c();
~c();
// int operator()(int i) { return n[i]; }
// there is a friend global function, that when receives a "c" object,
// as a parameter, or declares a "c" object, as a local variable,
// this function, will have access to the "public" members of "c" objects,
// the "thisref" will be removed, when turned into a method
friend int c_subscript(c thisref, int i) ;
};
int c_subscript(c* thisref, int i)
{
return c->n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c_subscript(objC, 3);
// do something with "x"
return 0;
} // int main(...)
Local function ( "method" ) example:
class c {
private:
int n[10];
public:
c();
~c();
// int operator()(int i) { return n[i]; }
int subscript(int i) ;
};
int c::subscript(int i)
{
return this.n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c->subscript(objC, 3);
// do something with "x"
return 0;
} // int main(...)
And, finally use the overloaded operator:
class c {
private:
int n[10];
public:
c();
~c();
int subscript(int i) ;
int operator()(int i) { return this.subscript(i); }
};
int c::subscript(int i)
{
return this.n[i];
}
int main()
{
c* objC() = new c();
// do something with "objcC"
int x = c->subscript(3);
// do something with "x"
int x = c(3);
// do something with "x"
return 0;
} // int main(...)
Note that in the final example, I keep the method with a unique identifier.
Cheers.
Could always do this:
class cc {
private:
c *_mass;
public:
c& mass() const {return *_mass;};
};
Now..
cc1->mass()(1);
If mass were an object, not a pointer, you could use the syntax you want:
class cc {
private:
public:
c mass;
cc();
~cc();
const c& operator*() const {return mass;};
};
…
cc1->mass(1);
You can with
(*(*cc1))(1)
because operator() is applied to an object, not a pointer.
You can use
(**cc1)(1);
Or
cc1->mass->operator()(1);