There is a class
class A {
public:
A() {};
private:
void func1(int) {};
void func2(int) {};
};
I want to add a function pointer which will be set in constructor and points to func1 or func2.
So I can call this pointer (as class member) from every class procedure and set this pointer in constructor.
How can I do it?
class A {
public:
A(bool b) : func_ptr_(b ? &A::func1 : &A::func2) {};
void func(int i) {this->*func_ptr(i);}
private:
typedef void (A::*func_ptr_t_)();
func_ptr_t_ func_ptr_;
void func1(int) {};
void func2(int) {};
};
That said, polymorphism might be a better way to do whatever you want to do with this.
Add a member variable
void (A::*ptr)();
set it in the constructor
ptr=&A::func1;
(or use the initializer list) and call it in methods of A:
(this->*ptr)();
I compiled and ran this code. The various members need to be public so you can pass them into the constructor. Otherwise, here you go.
However, I agree with other posters that this is almost definitely a bad thing to do. ;) Just make invoke pure virtual, and then make two subclasses of A which each override invoke().
#include <iostream>
using namespace std;
class A;
typedef void(A::*MyFunc)(int) ;
class A {
public:
A() {}
A(MyFunc fp): fp(fp) {}
void invoke(int a)
{
(this->*fp)(a);
}
void func1(int a) { cout << "func1 " << a << endl; }
void func2(int a) { cout << "func2 " << a << endl; }
private:
MyFunc fp;
};
int main()
{
A* a = new A( & A::func1 );
a->invoke(5);
A* b = new A( & A::func2 );
b->invoke(6);
}
See boost::function for a way to handle function and class member pointers in a more OO/C++ manner.
For example (from the documentation) :
struct X
{
int foo(int);
};
boost::function<int (X*, int)> f;
f = &X::foo;
X x;
f(&x, 5);
I suggest you use functor(or function object), rather than function pointer, because the former is safer, and function pointer can be difficult or awkward to pass a state into or out of the callback function
A functor is basically a re-implementation of operator() of class A, for very detailed description please refer to Wikipedia: http://en.wikipedia.org/wiki/Function_object
The code should be something like this:
class A {
public:
A() {};
void operator()(int function_index, int parameter) {
if(function_index == 1)
func1(parameter);
else if(function_index == 2)
func2(parameter);
else
{ //do your other handling operation
}
}
private:
void func1( int ) {};
void func2( int) {};
};
By using that class:
A a;
a(1, 123); //calling func1
a(2, 321); //calling func2
Why do you think it's a bad thing to do. I just need one function pointer and I don't want to create two subclasses for this. So why is it so bad?
Some example...
class A; // forward declaration
typedef void (A::*func_type)(int);
class A {
public:
A() {
func_ptr = &A::func1;
}
void test_call(int a) {
(this->*func_ptr)(a);
}
private:
func_type func_ptr;
void func1(int) {}
void func2(int) {}
};
Related
I have a nested class B inside class A. I need to pass a custom function with one integer argument and return type of void at runtime to class B.
This is how I tried to do it. First I passed the function through the constructor of A. And then to pass it to B, I tried to use pointer to member function. However I can't figure out how to call function foo() inside doStuff().
class A {
void(*f)(int);
A(void(*f)(int)) : f(f) {};
class B {
void(*A::*foo)(int) = &A::f;
void doStuff() {
var = 10;
*foo(var); //Doesn't work
}
};
};
void testFunction(int a) {
//do something
}
A a(testFunction);
What is the correct way to call it? And does this solution make sense as the whole?
Edit: Possible alternative solution:
class A {
A(void(*f)(int)) {
b = B(f);
}
class B {
void(*f)(int);
B() {}
B(void(*f)(int)) : f(f) {}
void doStuff() {
var = 10;
f(10);
}
};
B b;
};
Note that in order to call a pointer-to-function member of A you need an object of type A to call it on. In the example below, the reference to an A object was passed as an argument to B::doStuff.
#include <iostream>
class A
{
public:
void (*f)(int);
A(void (*f)(int)) : f(f) { }
class B {
public:
void (*A::*foo)(int) = &A::f;
void doStuff(A &a) {
(a.*foo)(10);
}
};
};
void testFunction(int a) {
std::cout << "inside testFunction(" << a << ")" << std::endl;
}
int main()
{
A a(testFunction);
A::B b;
b.doStuff(a);
}
Example output: inside testFunction(10).
Is it possible to pass this by default ?
Here is what I currently have
class A
{
public:
template<typename T>
void dowithT(T t) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
a.dowithT(this);
}
};
This function requires passing this from the caller of the function every time. So I wondered if there is a way to encapsulate this task, so that you don't need to pass this to dowithT.
I tried to do something like this:
class A
{
public:
// '= this' doesn't compile
template<typename T>
void dowithT(T t = this) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' without 'this'
a.dowithT();
}
};
Unfortunately, I can't use templates, so my first solution isn't an option.
Is this possible?
Edit: I gave a concrete answer with my own implementation below. Also with a few mor deatils of what I wanted in the end.
TL;DR No, this is not possible.
this is not the same type in every class, you can't generalize it, so no, not possible.
Additionally, what would this be if doWithT() was called from a non-member function? nullptr?
That's why it isn't possible. You have to use a template.
Instead of B having a member of type A, it can inherit from A, and use something like the "curiously recurring template pattern."
If you cannot make class A a template, you can still do it like so:
class A
{
protected:
template <class T>
void dowithT()
{
T* callerthis = static_cast<T*>(this);
// callerthis is the "this" pointer for the inheriting object
cout << "Foo";
}
};
class B : public A
{
public:
B()
{
dowithT<B>();
// Or A::dowithT<B>();
}
};
dowithT() must only be called by an inheriting class (hence I made it protected), with the template parameter the caller's own type, or you'll break everything.
You may achieve exactly what you want by using a private mixin class to provide the dowithT method that takes no arguments:
#include <iostream>
#include <typeinfo>
class A
{
public:
template<typename T>
void dowithT(T* t) {
std::cout << "Hello, World" << typeid(*t).name() << std::endl;
}
};
template<class Owner>
struct calls_a
{
void dowithT()
{
auto p = static_cast<Owner*>(this);
p->a.dowithT(p);
}
};
class B
: private calls_a<B>
{
friend calls_a<B>;
A a;
public:
B()
{
//Calling 'dowithT' with 'this'
dowithT();
}
};
int main()
{
B b;
}
No, it is not possible. There is nothing really special about this when used as an argument to a function taking T* (template or not), it's just a pointer like any other.
this A is different from this B. In your first code, this refers to the caller, while in the second this refers to the callee. Thus what you want to do isnt really possible.
Here's one possibility, which might, or might not suit your needs:
template<typename T>
class A
{
public:
A(T t) : t(t) {}
void dowithT()
{
cout << "Foo";
}
private:
T t;
};
class B
{
public:
A<B*> a;
B() : a(this)
{
a.dowithT();
}
};
You could use a private method in class B that acts as a relay, and use the constant nullptr as a special value for this, if you want to be able to pass other values:
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
innerdo();
}
private:
void innerdo(B *p = nullptr) {
if (p == nullptr) p = this;
a.dowithT(p);
}
};
If you only need to pass this it is even simpler
void innerdo() {
a.dowithT(this);
}
After trying out various things you mentioned, I'd like to give my answer/solution to the problem myself to clarify some details:
#include <iostream>
using namespace std;
#include <functional>
template <typename CallerType>
class AFunctionConstructor{
private:
virtual void abstr()
{}
public:
typedef void(CallerType::*CallerTypeFunc)();
function<void()>* constructFunction(CallerTypeFunc func)
{
CallerType* newMe = dynamic_cast<CallerType*> (this);
return new function<void()>(std::bind(func,newMe));
}
};
class A : public function<void()>
{
protected:
public:
A();
A(function<void()>* func) : function<void()>(*func)
{}
};
// now create ressource classes
// they provide functions to be called via an object of class A
class B : public AFunctionConstructor<B>
{
void foo()
{
cout << "Foo";
}
public:
A a;
B() : a(constructFunction(&B::foo)) {}
};
class C : public AFunctionConstructor < C >
{
void bar()
{
cout << "Bar";
}
public:
A a;
C() : a(constructFunction(&C::bar)) {}
};
int main()
{
B b;
C c;
b.a();
c.a();
cout << endl;
A* array[5];
array[0] = &b.a; //different functions with their ressources
array[1] = &c.a;
array[2] = &b.a;
array[3] = &c.a;
array[4] = &c.a;
for (int i = 0; i < 5; i++) //this usability i wanted to provide
{
(*(array[i]))();
}
getchar();
return 0;
}
Output :
FooBar
FooBarFooBarBar
This is as far as i can press it down concerning examples. But i guess this is unsafe code. I stumbled across possible other and simpler ways to achieve this (other uses of std::function and lambdas(which i might have tried to reinvent here partially it seems)).
At first I had tried to pass "this" to the bind function in function<void()>*AFunctionConstructor::constructFunction(CallerTypeFunc func)
,though, which i now get through the dynamic upcast.
Additionally the functionality of AFunctionConstructor was first supposed to be implemented in a Constructor of A.
I have 2 class, I would like to pass a method from one to other by callback!
See that I also wish to hold the address of this method using void (*callBack)();
I'm used to do this in C, but I dont know how to do this in c++;
#include <iostream>
using namespace std;
class A
{
private:
void (*callBack)(); //to hold the address of the method
public:
A();
void setCallBack(void(*cB)());
void useCallBack();
};
A::A()
{
}
void A::setCallBack(void(*cB)())
{
callBack = cB;
}
void A::useCallBack()
{
callBack();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(someMethod);
Aguy->useCallBack()
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
The problem is that:
void (*callBack)();
This is not a pointer to a method. This is a pointer to a function.
To have a pointer to a method you need to specify the class the method is in.
void (B::*callBack)();
Then when you call it you need to call it via an object.
void A::useCallBack(B* b)
{
(b->*callBack)();
}
But this is probably not what you want.
What you really want is a wrapper that encapsulates all this.
I would take a look at std::function. This will allow you to wrap a method call and an object into a single object that you can then call.
std::function<void()> callback;
Just replace all your occurrences of void(*cB)() with std::function<void()> then you can bind an instance of the object to the method at the call point.
Aguy->setCallBack(std::bind(&B::someMethod, this));
This also allows you to seemly pass any normal function or functor as a callback.
void print()
{ std:cout << "It worked\n";
}
...
Aguy->setCallBack(&print);
struct Printer
{
void operator()() const
{
std::cout << "It worked with obejct\n";
}
}
...
Aguy->setCallBack(Printer());
If you need to pass member function pointers see the modified code. it uses modern c++ constructs.
#include <iostream>
#include <functional>
using namespace std;
class A
{
private:
typedef std::function<void()> some_void_function_type;
some_void_function_type f_;
public:
A();
void setCallBack(some_void_function_type f);
void useCallBack();
};
A::A()
{
}
void A::setCallBack(some_void_function_type f)
{
f_ = f;
}
void A::useCallBack()
{
f_();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(std::bind(&B::someMethod, this));
Aguy->useCallBack();
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
See c++ - <unresolved overloaded function type> for details.
To quote the answer:
In C++, member functions have an implicit parameter which points to
the object (the this pointer inside the member function). Normal C
functions can be thought of as having a different calling convention
from member functions, so the types of their pointers
(pointer-to-member-function vs pointer-to-function) are different and
incompatible. C++ introduces a new type of pointer, called a
pointer-to-member, which can be invoked only by providing an object.
Put static on someMethod:
class B
{
private:
A * Aguy;
public:
B();
static void someMethod();
void otherMethod();
};
void B::otherMethod() {
Aguy->setCallBack(B::someMethod);
Aguy->useCallBack(); // adding missing semicolon
}
The code snippet below produces an error:
#include <iostream>
using namespace std;
class A
{
public:
virtual void print() = 0;
};
void test(A x) // ERROR: Abstract class cannot be a parameter type
{
cout << "Hello" << endl;
}
Is there a solution/workaround for this error other/better than replacing
virtual void print() = 0;
with
virtual void print() = { }
EDIT: I want to be able to pass any class extending/implementing the base class A as parameter by using polymorphism (i.e. A* x = new B() ; test(x); )
Cheers
Since you cannot instantiate an abstract class, passing one by value is almost certainly an error; you need to pass it by pointer or by reference:
void test(A& x) ...
or
void test(A* x) ...
Passing by value will result in object slicing, with is nearly guaranteed to have unexpected (in a bad way) consequences, so the compiler flags it as an error.
Of course, change the signature:
void test(A& x)
//or
void test(const A& x)
//or
void test(A* x)
The reason your version doesn't work is because an object of type A doesn't logically make sense. It's abstract. Passing a reference or pointer goes around this because the actual type passed as parameter is not A, but an implementing class of A (derived concrete class).
To be absolutely clear, the problem is, whenever you define a class:
#include <iostream>
class foo {
public:
char *name = (char *)"foo";
};
and pass an instance of that class to a function, it creates a copy:
void bar(foo a) {
a.name = (char *)"bar";
}
int main() {
foo x;
bar(x);
std::cout << x.name << std::endl; // foo
return 0;
}
With regard to inheritance, it creates a copy as an instance of the base class:
#include <iostream>
class foo {
public:
char *name = (char *)"foo";
};
class bar: public foo {
public:
char *name = (char *)"bar";
};
void baz(foo a) {
std::cout << a.name << std::endl;
}
int main() {
bar x;
baz(x); // again, foo
return 0;
}
so, by doing
void baz(AbstractType a) {
...
}
you're telling the compiler to copy an AbstractType as an instance of AbstractType itself, which is illegal.
Pass it as const AbstractType &a to prevent copying.
Let say we have a base class and its two derived classes; The base class owns a method execute and each derived class implements a different version of this method with different types and number of arguments; I can't use a virtual method because signature should be then exactly the same for each derived class; My goal is to offer a base execute method which accepts any kind of arguments, deducts their types, and dispatch them to the right method in the right derived class; I took a look at the Visitor pattern, but I'm looking for a more flexible and elegant solution;
edit : I want to store those classes in a vector, so I need a base class
Here is my try (I don't know what to put in the body of base execute) under gcc 4.5:
class Base {
public:
Base();
~Base();
template<typename ...Args>
void execute(Args... arg)
{
//calls the right method
//execute(int i) or execute(int i, float f)
//as Args are int or int and float
}
};
class DerivedA : public Base
{
public:
DerivedA();
~DerivedA();
void execute(int i){ /*do something with i*/}
};
class DerivedB : public Base
{
public:
DerivedB();
~DerivedB();
void execute(int i, float f){/*do something with i and f*/}
};
void test()
{
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
int i = 5;
b1->execute(i); //should call DerivedA.execute(int i)
float f = 5.0f;
b2->execute(i, f); //should call DerivedB.execute(int i, float f)
}
The following uses an intermediate class in between the base and the derived class:
#include <utility>
#include <iostream>
#include <stdexcept>
template<typename... Args> class Intermediate;
class Base
{
public:
virtual ~Base() {}
template<typename ...Args>
void execute(Args... args)
{
typedef Intermediate<Args...>* pim;
if (pim p = dynamic_cast<pim>(this))
{
p->execute(std::forward<Args>(args)...);
}
else
{
throw std::runtime_error("no suitable derived class");
}
}
};
template<typename... Args> class Intermediate:
public Base
{
public:
virtual void execute(Args ... arg) = 0;
};
class DerivedA:
public Intermediate<int>
{
public:
void execute(int i)
{
std::cout << "DerivedA: i = " << i << "\n";
}
};
class DerivedB:
public Intermediate<int, float>
{
public:
void execute(int i, float f)
{
std::cout << "DerivedB: i = " << i << ", f = " << f << "\n";
}
};
int main()
{
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
int i = 5;
b1->execute(i); //should call DerivedA.execute(int i)
float f = 5.0f;
b2->execute(i, f); //should call DerivedB.execute(int i, float f)
}
You cannot have an arbitray (= unbounded) number of virtual functions in the base class. You have to decide which functions should be available and declare those. Otherwise you don't need virtual functions, and you could just make some compile-time dispatch, perhaps simply through overload resolution like this:
struct Base
{
void foo(int a) { dynamic_cast<DerA*>(this)->fooimpl(a); }
void foo(int a, float b) { dynamic_cast<DerB*>(this)->fooimpl(a, b); }
void foo(bool a, char b) { dynamic_cast<DerC*>(this)->fooimpl(a, b); }
virtual ~Base() { } // dynamic cast requires polymorphic class
};
You should add a check for validity, of course:
if (DerA * p = dynamic_cast<DerA*>(this)) { p->fooimpl(a)); }
Compile-time or runtime?
You need to know if you can decide at compile-time which method you want to call. If you want to decide at runtime, then that is called multiple dispatch and there is no built-in, short solution for it in C++ (see also the question Multiple dispatch in C++). You can sort of emulate it with the Visitor pattern or double dispatching. Here is a paper about implementing multimethod support for a C++ compiler by Bjarne Stroustroup and others.
Compile time implementation with a free function
If you know the type of your instances at compile time (i.e. you don't have to use Base* pointers), you can use a variadic template approach with static polymorphism (and you won't even need a common base class):
#include <iostream>
class DerivedA //: public Base
{
public:
void execute(int i)
{
std::cout << "I'm DerivedA::execute(int)! " << std::endl;
}
};
class DerivedB //: public Base
{
public:
void execute(int i, float f)
{
std::cout << "I'm DerivedB::execute(int, float)! " << std::endl;
}
};
template<typename Class, typename... Args>
void execInvoker(Class* obj, Args... args)
{
static_cast<Class*>(obj)->execute(std::forward<Args>(args)...);
}
int main(int argc, char* argv[])
{
DerivedA a;
DerivedB b;
int i = 5;
float f = 5.2f;
execInvoker(&a, i);
execInvoker(&b, i, f);
}
You will get compilation errors if you try to invoke an execute method that doesn't exist (wrong types, or wrong number of arguments). I tested the above code with g++ 4.6 and the output is the expected:
$ g++ -std=c++0x -Wall variadic.cpp
$ ./a.out
I'm DerivedA::execute(int)!
I'm DerivedB::execute(int, float)!
A similar approach without a free function
If you don't want to use a free function, you can use a template proxy class to save the type information.
template<typename Class>
class Proxy
{
private:
Class* obj;
public:
Proxy(Class* _obj) : obj(_obj) {}
template<typename... Args>
void execute(Args... args)
{
obj->execute(std::forward<Args>(args)...);
}
};
This allows the following code:
Proxy<DerivedA> proxy(&a);
proxy.execute(i);
An obvious advantage of this approach is that you can pass this proxy object to template functions such as this one:
template<typename Class>
void proxyUser(Proxy<Class>& p)
{
p.execute(4, 0.3f);
}
And it will call the correct execute. For specific cases, you can specialize this template function.
If I understand correctly what you are trying to accomplish, you could find it useful having a look at the "double dispatch" pattern:
double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call (source)
Roughly: your client object calls "execute" on the target object:
target.execute(client);
the target object calls a method on an intermediate object that acts as an extended virtual table (actually, a multi-dispatch table):
dispatchTable.execute(client, *this); //-- target calls this
and dispatch table at its turns calls the right method (with the complete signature) on the target object:
<get arguments from client>
target.specific_execute(arguments)
Alternatively, and possibly more conveniently, the dispatch table mechanism can be offered by the client object itself. So, target::execute calls:
client.execute(target);
and client::execute(target) will finally call:
target.specific_execute(args);
The client class will provide a set of overaloaded execute methods, each for a specific target type. The method will encapsulate the knowledge about the specifics of that object execute arguments.
This could require some refactoring of your design (in the first approach, client has to offer a way to retrieve the arguments to the call), and it possibly looks like quite a low-level implementation (a dispatch table), but it is a clean approach, IMO.
class Client;
struct Base {
virtual void dispatch(Client& c);
void execute(Base& b) {
std::cout << "void execute(Base&)" << std::endl;
}
};
struct DerivedA : public Base {
void exec(int i){
/*do something with i*/
std::cout << "void execute(int i)" << std::endl;
}
};
struct DerivedB : public Base {
void exec(int i, float f)
{
std::cout << "void execute(int i, float f)" << std::endl;
}
};
struct Client {
int i;
float f;
void execute(Base& obj) {
}
void execute(DerivedA& obj) {
obj.exec(i);
}
void execute(DerivedB& obj) {
obj.exec(i, f);
}
void doTest() {
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
b1->dispatch(*this);
b2->dispatch(*this);
}
};
void Base::dispatch(Client& c) {
c.execute(*this);
}
void DerivedA::dispatch(Client& c) {
c.execute(*this);
}
void DerivedB::dispatch(Client& c) {
c.execute(*this);
}
int main (int argc, char * const argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
Client c;
c.doTest();
return 0;
}