How to use function pointers in different classes? - c++

Please check the following code. Why it is wrong and how to fix? Thank you.
class A
{
public:
class B
{
public:
B(int(*cf)())
{
f = cf;
}
int (*f)();
};
B *b;
A()
{
b = new B(this->a);
}
int a()
{
}
};
int main()
{
A a;
}
compilation error:

If you absolutely need to call a function by pointer you will need to use a pointer to member function instead of a pointer to function. A pointer to member function has a different declaration syntax that includes the class type the function belongs to. In your case the parameter declaration would look like int (A::*cp)(). You will also need to change the declaration of the f member variable to int (A::*f)().
In order to call a pointer to member function you need to have a pointer to an object of the type the function belongs to. You also need to use one of the pointer to member operators; ->* or .*
void call(A* c, int (A::*f)())
{
(c->*f)(); // call member function through pointer
}
The extra set of parenthesis is required due to the order of precedence of operators.
The following code includes the changes necessary for you to use pointer to member functions.
class A
{
public:
class B
{
public:
// Take a pointer to member function.
B(int(A::*cf)())
{
f = cf;
}
void call(A* c)
{
(c->*f)();
}
int (A::*f)(); // pointer to member function
};
B *b;
A()
{
b = new B(&A::a);
}
int a()
{
return 0;
}
};
int main()
{
A a;
a.b->call(&a);
}
I also recommend that you consider using std::function and std::bind (or their Boost equivalents if you do not have a C++11 compiler).

Do not use function pointers in the first place when using C++.
There is an easier and more elagant solution - an interface.
i.e.
class Interface {
public:
virtual int CallMe() = 0;
};
class B : public Interface { int CallMe() { return 5; };
class A : public Interface {
private:
Interface *m_i = 0;
public:
A(Interface *i) : m_i(i) { }
A() : m_i(this) { };
void DoIt() { cout << m_i->CallMe() << endl; }
int CallMe() { return 8; }
};
int main() {
A a(new B); // Coult be any object that implements Interface (as yes it is a memory leak
A aa();
a.DoIt(); // Will print 5
aa.DoIt(); // WIll print 8
return 0;
}

Related

Pass function pointer to nested class

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?

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.

Assign pointer to a function the address of a pointer to function object

Is it possible in C++?
For example I have a pointer to a function that takes no parameters and its return type is void:
void (*f)();
and and a function object:
class A
{
public:
void operator()() { cout << "functor\n"; }
};
Is it possible to assign to f the address of an A object? And when I call f() to call the A functor?
I tried this but it doesn't work:
#include <iostream>
using namespace std;
class A
{
public:
void operator()() { cout << "functorA\n"; }
};
int main()
{
A ob;
ob();
void (*f)();
f = &ob;
f(); // Call ob();
return 0;
}
I get C:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)'
There is no context in which this conversion is possible
Is there any way to achieve this?
You can't do it in the way you've specified, because:
operator() must be a nonstatic function (standards requirement)
a pointer to a non-static function must have an implicit parameter - the pointer to the class instance
your call to f() does not give any indication on which instance of the object A your function is called
Using C++11 and std::function, as Stephane Rolland pointed out, may do the trick - you'll be specifying the pointer to the object in the binding:
std::function<void(void)> f = std::bind(&A::operator(), &ob);
(See question on using std::function on member functions)
If you use C++11, could use std::function
#include <functional>
std::function<void()> f;
int main()
{
A ob;
ob();
f = ob; // f refers to ob
f(); // Call ob();
return 0;
}
Yes it's kind of possible using a C++1/C++0x feature, but to achieve this you should use the std::function which can address to the two types, functions and object functions.
#include <functional>
class A
{
public:
void operator()() { }
};
int main()
{
std::function<void(void)> aFunction;
A ob;
aFunction = ob;
// or as another user said
// aFunction = std::bind(&A:operator(), &ob);
aFunction();
void (*f)();
aFunction = f;
aFunction();
return 0;
}
and if you're stuck with C++03, you could play with std::mem_fun and std::ptr_fun
How about some workaround like this:
Basically you want to have a common way of calling member functions and functions. Then maybe you could create a wrapper that would represent a generic pointer to either a function or member function. Let's say you have Base class and you want to be able to invoke operator() of all derived classes. Then you also have a function() that you want to invoke as well:
class Base
{
public:
virtual void operator()() = 0;
};
class A : public Base
{
public:
void operator()(){ std::cout << "A()" << std::endl; }
};
void function()
{
std::cout << "function" << std::endl;
}
If you create an wrapper that allows you to construct your custom pointer (MyFncPtr):
typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();
class MyFncPtr
{
public:
MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL) { }
void invoke()
{
if (baseObj && baseFnc)
(baseObj->*baseFnc)();
else if (fnc)
fnc();
}
private:
BaseFncPtr baseFnc;
Base* baseObj;
FncPtr fnc;
};
you could achieve it like this:
A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();
outputs:
A()
function
Hope this helps :)

How to re-type pointer to a class and be able to reach classes functions based on it's type?

I'm writing a C++ code which should populate a screen (and it's behaviour) based on a function from the object pointer was initiated with. Let's better show it on a code:
class A:parentClass {
public:
int X () {return 5;}
}
class B:parentClass {
public:
int X () {return 3;}
}
class C:parentClass {
public:
int X () {return 1;}
}
main {
parentClass *p;
p = new A;
printf("%d\n,p.x); //to return 5
delete p;
p = new B;
printf("%d\n,p.x); //to return 3
}
I'm getting something like this on compilation:
‘class parrentClass’ has no member named ‘x’
I know that this is wrong, as parrentClass simply doesn't have that member, but I don't have an idea how to solve this. I tried to go through templates, but I'm not getting anywhere.
I also tried to replace "parentClass *p;" with "int *p;", but then I'm getting:
cannot convert ‘CardsFrame*’ to ‘int*’
Thanks for your suggestions in advance,
Jan
You need to declare the X() method virtual on the parent class for this to work:
class ParentClass
{
public:
virtual int X();
};
To be clear: the following is a complete working example (compiled with gcc):
#include <iostream>
class ParentClass {
public:
virtual int x() = 0;
};
class A : public ParentClass {
public:
int x() { return 5; }
};
class B : public ParentClass {
public:
int x() { return 3; }
};
class C : public ParentClass {
public:
int x() { return 1; }
};
int main() {
ParentClass *p;
p = new A;
std::cout << p->x() << std::endl; // prints 5
delete p;
p = new B;
std::cout << p->x() << std::endl; // prints 3
delete p;
}
You really need to get your basics right as your syntax is all wrong. You need to use p->X() to call the function. And to answer the actual question make X() virtual in the base class.
printf("%d\n,p.x); //to return 5
should be:
printf("%d\n,p->X()); //to return 5
Also, X() should be virtual in the Base class.

Class member function pointers in C++

I want to call a member function of another class on an object, but I cant seem to figure out how this works. As example code on how it should work:
Class A {
void somefunction(int x);
}
Class B : A {
void someotherfunction(int x);
}
Class C {
void x() {
callY(&ofthefunction);
} //here you call the function, you dont have an object yet, and you don't know the argument yet, this will be found in function callY
void Y(*thefunction) {
find int x;
if(something)
A a = find a;
a->thefunction(x);
else
B b = find b;
b->thefunction(x);
}
}
I hope this makes sence, It is also possible to split this in 2 methods, Y1 and Y2, but seeing as 90% of the code is the same (finding things in a XML file), only the object and argument where to save it is different, i'd like to do this
You can use something known as a virtual function. By the way, your syntax is hideous, it's class not Class, you need braces for your conditionals, and a judicious application of public, some extra semicolons, etc. It would be appreciated if you would go near a compiler before coming here, y'know.
class A {
public:
virtual void somefunction(int x);
};
class B : public A {
public:
virtual void somefunction(int x);
};
void func(A& a) {
int x = 0;
// Do something to find x
a.somefunction(x);
// calls A::somefunction if this refers to an A
// or B::somefunction if it's a B
}
int main() {
A a;
func(a); // calls A::somefunction
B b;
func(b); // calls B::somefunction
}
What you want to do can be done, although I woudn't solve it this way:
class A {
public:
virtual int doit(int x) { return x+1; }
};
class B : public A {
public:
int doit2(int x) { return x*3; }
int doit(int x) { return x*2; }
};
int foo(int (A::*func)(int), int x, bool usea) {
if (usea) {
A a;
return (a.*func)(x);
} else {
B b;
return (b.*func)(x);
}
}
int main() {
int (A::*bla)(int) = &A::doit;
foo(bla, 3, true);
foo(bla, 3, false);
}
However, for this to work, the following has to be satisfied:
You must use function pointers of the base class (e.g. int (A::*bla)(int)), otherwise you won't be able to call it on that base class (e.g. int (B::*bla)(int) can only be used on B instances, not on A instances, even if the method is already defined in A).
The methods must have the same names as in the base class
To use overriding (e.g. different impl in derived class), you have to use virtual functions.
But I would rather rethink your design...
No, that won't work at all. A pointer to a member of A will always point to that function, even when it's called on B because B inherits from A.
You need to use virtual functions. I see DeadMG has beaten me to it.