I'd like to call a few methods of classes 'A' and 'B' from the class 'Caller'. I need to use a function pointer because I want to call different methods.
My method gets called, but when I try to access a member variable from it, my program crashes ('program.exe has stopped working').
How come that happens?
#include <iostream>
using namespace std;
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
class A
{
public:
A() : n(0) {}
void foo(int bar)
{
cout << "A::foo called (bar = " << bar << ", n = " << n << ")" << endl; // the crash occurs here, and 'this' equals 0 at this point
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
class B
{
public:
B() : n(0) {}
void fooo(int bar)
{
cout << "B::fooo called (bar = " << bar << ", n = " << n << ")" << endl; // same here if I call B::fooo first
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
int main()
{
A myA;
B myB;
myA.setNum(128);
myB.setNum(256);
Caller<A> cA(&myA, &A::foo);
Caller<B> cB(&myB, &B::fooo);
cA.invoke(10);
cB.invoke(20);
return 0;
}
Thank you in advance.
EDIT : I use VS2017 and I can build my program without getting any compiler errors.
My method gets called, but when I try to access a member variable from it, my program crashes ...
Because you forgot to assign passed obj to o pointer in your Caller:
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
o = obj; // << == you need this!
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
Also, in general it's better to use member initializer lists:
Caller::Caller(T* obj, myFunc fp) : o(obj), f(fp)
{
}
Related
as the below code, I don't want so many "if else"
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//..... more functions fn()...
};
class B
{
public:
void f(int n)
{
//vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; //this usage is not correct
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
I want to create a vector and use std::function to avoid using so many if-else , like vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; but it doesn't work, maybe the usage of std::function is not very correct. How should I do? Or is there any other good way to solve the problem of if else, I think use so many switch-case is also not very elegant :)
update:
Some answers have already solve my problem about the usage of std::function in my earlier code;
More generally, considering the below code, if the member functons A::f1(), A::f2().... have different return types, but still have some connection that they derived from a same base class , what's the good way to implement the logic of if else in B::f()?
class Base
{
public:
virtual ~Base()=default;
};
class D1 : public Base
{
public:
};
class D2 : public Base
{
public:
};
class D3 : public Base
{
public:
};
// ....maybe more class derived form Base
class A
{
public:
D1* f0()
{
cout << "f0" << endl;
return &d1;
}
D2* f1()
{
cout << "f1" << endl;
return &d2;
}
D3* f2()
{
cout << "f2" << endl;
return &d3;
}
//more fn()....
private:
D1 d1;
D2 d2;
D3 d3;
//.....
};
class B
{
public:
void f(int n)
{
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
You can use std::function with a lambda wrapper,
vector<function<void()>> f_v {[this]() { obj_a.f0(); },
[this]() { obj_a.f1(); },
[this]() { obj_a.f2(); }};
f_v[n]();
or use pointer-to-members directly,
vector<void (A::*)()> f_v { &A::f0, &A::f1, &A::f2 };
(obj_a.*f_v[n])();
If you are aiming at speed and you know the number of methods, avoid using std::vector for the extra indirection. Use std::array as it will hit cache with the current object.
For this simple case, you don't necessarily need to use std::function, which is a very heavy object to call. You can use pointers to members like this:
#include <iostream>
#include <array>
using namespace std;
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//.....
};
class B
{
public:
B() {
fn[0] = &A::f0;
fn[1] = &A::f1;
fn[2] = &A::f2;
}
void f(int n)
{
((obj_a).*(fn[n]))();
}
private:
using Fn = void (A::*)();
std::array<Fn,3> fn;
A obj_a;
};
Code: https://godbolt.org/z/z4KqKvn99
Your approach seems correct. You just need to std::bind those member functions like
class B{
std::vector <std::function <void()>> m_vec_functs;
...
B(const A& a)
{
m_vec_functs.push_back(std::bind(&A::f0, a));
m_vec_functs.push_back(std::bind(&A::f1, a));
}
void f(unsigned int n)
{
m_vec_functs[n];
}
...
};
Then you can access each individual function by its index, knowing their order.
How to read the following code for main?
I do not know this
Code :
class one
{
public:
void operator()() const
{
f();
f1();
}
};
I want to call the operator To main?
void operator()() const defines a function call operator, which can be used as:
one ob;
ob(); // calls ob.operator()()
For another, more complete, example.
#include <iostream>
class Two
{
public:
int operator()(const char *str) const
{
std::cout << "operator() called with " << str << std::endl;
return 101;
}
};
int main()
{
Two two;
int n = two("'test'");
std::cout << "operator() returned " << n << std::endl;
}
Output:
operator() called with 'test'
operator() returned 101
You can create an instance of the class in the main function and call the function using that instance.
class one
{
public:
void operator()() const
{
f();
f1();
}
};
int main() {
one obj_one;
// calling the member function -> method
obj_one.operator()();
return 0;
}
In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}
#include <iostream>
struct object1 {
object1(int v) : type(1), value(v) {}
int type;
int value;
};
struct object2 {
object2(int v) : type(2), value(v) {}
int type;
int value;
};
template <typename HeaderType>
void foo(HeaderType * hdr) {
std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
}
// this function doesn't work
template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
if (type == 1) {
object1 h(val);
handler(&h);
} else {
object2 h(val);
handler(&h);
}
}
int main() {
int type = 1;
int val = 1;
// this part works
if (type == 1) {
object1 h(val);
foo(&h);
} else {
object2 h(val);
foo(&h);
}
// trying to replicate the above behavior in a more abstract way,
// ideally via a function call of the following sort
//
// dispatch(type, val, ..foo..? );
}
The above program takes an input value, uses it to decide what type of object to create, then calls a function foo with a pointer to that object.
Question: Is it possible to create this sort of abstraction where the caller of dispatch doesn't know the exact types that foo will be called with but the dispatch function doesn't know the specific function that is going to be called?
With
template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
if (type == 1) {
object1 h1(val);
handler(&h1);
} else {
object2 h2(val);
handler(&h2);
}
}
All branches should be valid, so handler(&h1) and handler(&h2) should be valid calls.
For that, handler may be a generic lambda (since C++14) as suggested in comment:
dispatch(type, val, [](auto a) {return foo(a);} );
or you may create your own functor:
struct foo_caller
{
template <typename HeaderType>
void operator () (const HeaderType* hdr) const {
std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
}
};
And then call it:
dispatch(type, val, foo_caller());
Given this code:
template < int I >
class Foo
{
public:
int v;
Foo() { v = I; }
virtual ~Foo() {}
};
class Bar : public Foo<0>, public Foo<3>
{
public:
template < int I >
int getValue() { return Foo<I>::v; }
};
int main() {
Bar b;
cout << b.getValue<0>() << endl; // prints 0
cout << b.getValue<3>() << endl; // prints 3
cout << b.getValue<4>() << endl; // compiler error
return 0;
}
Is it possible to iterate over all Foo<i> classes from which Bar inherits? We can assume that i is between 0 and some maximum N. In pseudocode:
for ( int i = 0; i < N; i++ )
{
if ( Bar inherits from `Foo<i>` )
{
cout << Foo<i>::v << endl;
}
}
Here you go (live example):
struct _do { template <typename... A> _do(A&&...) { } };
template <int... I>
class Bar_impl : public Foo<I>...
{
public:
template < int K >
int getValue() { return Foo<K>::v; }
template <typename F>
void loop(F&& f) { _do{(std::forward<F>(f)(getValue<I>()), 0)...}; }
};
using Bar = Bar_impl<0,3>;
Now Bar implementation holds all indices of base classes in variadic parameter I... and derives all base classes Foo<I>... in a variadic fashion.
Function loop iterates over all bases using the auxiliary struct _do. You can pass an arbitrary function, lambda or function object f to loop. Then f will be called on getValue<I>() for all I..., i.e., on member v of every base class.
You use this as follows:
void print(int i) { cout << i << " "; }
int main() {
Bar b;
b.loop(print); // prints 0 3
cout << endl;
}
In other words, you don't need to detect if an object is an instance of some class. You make the object know its own bases by construction.
Now you may realize that if you make Foo a template on the member type (instead of int), you are quite close to start building your own very basic tuple.