Using C++ non-static member functions as callbacks and class scope issue - c++

My code contains the following:
1) A.h (cannot be changed by me as it's defined by somebody else)
typedef void (*fnctPtr)(int input);
class A
{
A(fnctPtr func); //Constructor for A
//... Other details omitted
};
2) B.h (my code)
#include "A.h"
class B
{
public:
B() : m_a(m_private_method){}; //Ptr to non static method.
void m_private_method(int input);
A m_a; //Member variable
};
3) A simple main.cpp declaring and instance of B
#include <iostream>
#include "B.h"
int main()
{
B b;
return 0;
}
It does not compile, as m_a requires initialization with a fnct pointer of type void (*)(int input), not void (B::*)(int input).
Any advice on how to achieve what I want?
Thanks

If you're really stuck with typedef void (*fnctPtr)(int input);, then you have to provide a pointer to a function that takes a int as parameter and returns nothing.
When you' providing a pointer-to-member function of class B taking an int and returning nothng, you really provide either something that can be seen as:
either function taking two arguments, the instance of the classB and an int.
or a virtual function that need to lookup in B instance to know what function taking two arguments (B and int) to call.
There is no way to make any of those fit into the first definition.
You may find a hack (keeping an instance globally and using it inside an helper function would be one), but this is highly dependent of the full problem.

Related

sending data from one field of a class back to the class

I have one class "A" that contains some field, one of these fiels is a class "Z", so I want to send data from this field(which is a class) to the class "A", when I tried to send data from the class "A" to the "Z" via reference it worked, but now I can't see how can I process data in the reverse way.
here's the code:
#ifndef SCREEN_AGENDAVIEW_HPP
#define SCREEN_AGENDAVIEW_HPP
#include <gui_generated/screen_agenda_screen/Screen_agendaViewBase.hpp>
#include <gui/screen_agenda_screen/Screen_agendaPresenter.hpp>
#include <string>
class Screen_agendaView : public Screen_agendaViewBase
{
public:
Screen_agendaView();
virtual ~Screen_agendaView() {}
void Open_Container()override;
void SendToView(std::string text);
protected:
CustomContainer_event ce;
};
#endif // SCREEN_AGENDAVIEW_HPP
#include <gui/screen_agenda_screen/Screen_agendaView.hpp>
Screen_agendaView::Screen_agendaView():ce(*this)
{
}
void Screen_agendaView::Open_Container()
{
customContainer_event1.setVisible(true);
customContainer_event1.invalidate();
}
void Screen_agendaView::SendToView(std::string text)
{
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%s", text);
textArea1.setWildcard(textArea1Buffer);
textArea1.invalidate();
}
#ifndef CUSTOMCONTAINER_EVENT_HPP
#define CUSTOMCONTAINER_EVENT_HPP
#include <gui_generated/containers/CustomContainer_eventBase.hpp>
#include <gui/screen_agenda_screen/Screen_agendaView.hpp>
#include <string>
class CustomContainer_event : public CustomContainer_eventBase
{
public:
//CustomContainer_event();
CustomContainer_event(Screen_agendaView& d);
virtual ~CustomContainer_event() {}
virtual void initialize();
void Save_Note()override;
protected:
int pos_cursor = 0, shif = 1;
Screen_agendaView& s;
std::string text;
};
#endif // CUSTOMCONTAINER_EVENT_HPP
CustomContainer_event::CustomContainer_event(Screen_agendaView& s):s(s)
{
}
void CustomContainer_event::initialize()
{
CustomContainer_eventBase::initialize();
flexButton_Shift.setPressed(true);
}
void CustomContainer_event::Save_Note()
{
for (int i = 0; i <= pos_cursor; i++)
text += textArea2Buffer[i];
s.SendToView(text);
}
OP could pass class A's this (as pointer) or *this (as reference) to the constructor of the member var. of type class Z. Hence, class Z could store this pointer or reference as member itself and use it for accessing its "parent" class A instance.
Demo:
#include <iostream>
struct A; // forward declaration
struct Z {
A &a; // Z holds a reference to the associated instance of A
Z(A &a): a(a) { } // the associated instance of A is passed in constructor
void call(); // cannot be implemented before A became a complete type
};
struct A {
Z z; // A has a member var. of `struct Z` to which it will be associated
A(): z(*this) { } // A passes *this (the reference of its own) to z
void callZ()
{
std::cout << "A::callZ() called.\n";
z.call();
}
void call()
{
std::cout << "A::call() called.\n";
}
};
// now A is complete and Z::call() can use it to access (public) members of A &a
void Z::call()
{
std::cout << "Z::call() called.\n";
a.call();
}
int main()
{
A a;
a.callZ();
}
Output:
A::callZ() called.
Z::call() called.
A::call() called.
Live Demo on coliru
A class which stores a reference to another instance doesn't come without dangers. When such relations are designed then the (human) author should have the intended life-times in mind.
In this case, struct Z will be used as member of struct A exclusively. So, the associated instance of A will outlive it's member z.
If an instance of a class stores the reference to another instance which is destroyed before the first then the reference (inside the first) becomes dangling (i.e. referencing something which isn't existing anymore). As long as the reference isn't used nothing bad will happen. But accessing the dangling reference is Undefined Behavior. (It could crash or cause strange effects or (most accidental case) seem to work until something strange happens later.)
Example for wrong usage:
int main()
{
A *pA = new A();
Z z(*pA);
z.call(); // That's OK.
delete pA;
z.call(); // :-O BAD! z will call z.a.call() although z.a became dangling!
}
This design may cause an additional issue because struct A has to know struct Z to access its members and struct Z has to know struct A. That's a hen-egg-problem and C++ isn't the only effected language.
The solution is a forward declaration, in the above sample
struct A; // forward declaration
A forward declaration forms an incomplete type. It can be used to declare pointers and references. Pointers and references of incomplete types may be used only with certain constraints. E.g. sizeof of the pointer to an incomplete type is allowed because it actually doesn't depend on the type itself. (Pointers have always the same size.) In opposition, accessing the pointee of an incomplete type is not possible (as the pointee is of incomplete type and its contents simply not known as long as the type is incomplete).
Circular dependencies may require that declaration and definition of member functions are separated. In the above sample, it is remarked for Z::call():
// now A is complete and Z::call() can use it to access (public) members of A &a
void Z::call()
{
std::cout << "Z::call() called.\n";
a.call();
}
Defining classes in headers (as it is usual in C++ projects) may cause the issue of circular header dependencies.
If a.h declares struct A and z.h declares struct Z one might be attempted to #include "z.h" in a.h as well as #include "a.h" in z.h. This doesn't work. Either this will lead to a recursion or the author was clever enough to use header guards (to prevent duplicated definitions). In the latter case, one of the two involved headers will finally try to use the declaration of the other class in its own declaration and fail.
The solution is again a forward declaration of one involved class in the header of the other instead of the resp. #include. Both C++ sources may then include both header files without harm and provide the implementations which are based on both classes. This will, of course, require that the implementation of the resp. methods isn't done inline but separately done in the C++ source.

How should I access a function of a container class in a contained class object

I have the following class structure
class containingClass
{
int func1(int a);
containedClass containedClassObject;
}
I want to access func1 in containedClass objects. What will be the best way to achieve that?
A naive solution that comes to mind is to pass a function pointer to the containedClass's constructor, but then I get into a circular definition, as I need to pass a pointer to an object of the containingClass as well.
Any suggestions?
The containedClass required a contract/API/function to be fulfilled by the int func1(int) member of the containingClass. Unless the containedClass explicitly requires access to an instance of the containingClass for other purposes, the access can be provided via lambda (or std::bind) and the containedClass can have a std::function with the correct signature member that holds the lambda.
The only "trick" here would be to ensure that the lifetime of the objects are managed appropriately, i.e. the lifetime of the containingClass instance is at least as long as required for use in the containedClassObject object.
A sample;
#include <functional>
class containedClass {
std::function<int(int)> functor_;
public:
void setter(std::function<int(int)> functor) { functor_ = functor; }
};
class containingClass
{
int func1(int a);
containedClass containedClassObject;
public:
containingClass()
{
containedClassObject.setter([this](int a) -> int { return this->func1(a); });
}
};
Even if this already over a year old, I would like to help other seraching people.
Here is another example using a reference to the containing class. Tested with mingw32-g++ 4.9.2 and -std=c++98. Means it should work also with c++0x and c++11
#include <string>
#include <iostream>
using namespace std;
class clsDog;
class clsEar{
public:
clsDog& myDog;
clsEar(clsDog &dog);
};
class clsDog{
public:
clsEar ear;
void pain(string fromPart){
cout << "dog has pain in his " << fromPart << endl;
}
clsDog():ear(*this){};
};
clsEar::clsEar(clsDog &dog): myDog(dog){
myDog.pain("ear");
}
int main(){
clsDog dog;
}
First class clsDog makes it available for reference and pointers. NOT for actual values like non reference member variables.
In class clsEar a reference to clsDog is created using clsDog& myDog. The constructor can set the reference pointer in the initializer list. It is important that the containing class clsDog is passed by reference otherwise the compiler tell you that the class incomplete.
Because clsEar is now fully defined a normal member variable of clsEar can be defined in clsDog. Because clsEar's constructor needs a reference to clsDog it must be passed to it's constructor. This is done in the initialisier list of clsDog's constructor by passing *this.
Last but not least the implementation of clsEar::clsEar must be done. It is necessary to do this after the complete definition of clsDog to call the member functions or access member varibales of clsDog in clsEar. Otherwise the compiler will tell you again, that the class clsDog is of incomplete type.

How to std::bind a class function properly?

class A
{
public:
A();
void Func1(int,int);
void Func2(long,long);
private:
...
};
<implementation here>
In main:
std::vector<std::function<void(void)>> fl;
A a;
fl.push_back(std::bind(&a.Func1, 1,1));
Gives the error:
ISO C++ forbids taking the address of a bound member function to form a pointer to member function
Solution?
Edit: changed "A a();" to "A a;". No constructor here :P
Edit:
Selected Praetorian's reply as answer because it solves the problem.
Dietmar Kühl's is a good solution too but not the actual answer to the question.
Gotta be fair :D
Func1 is a non-static member function, so it must be invoked on an instance of A, which you'll need to bind as the first argument (the this pointer). Also, when creating a pointer to member function, the syntax is &ClassName::MemFuncName.
So you need
fl.push_back(std::bind(&A::Func1, &a, 1, 1));
Make sure that the lifetime of a does not end before you invoke the bound function.
Two issues. First,
A a();
is a function declaration. You need
A a;
Then,
fl.push_back(std::bind(&A::Func1, &a, 1,1));
You could also just not use std::bind():
std::vector<std::function<void(void)>> fl;
A a{};
fl.push_back([&](){ a.Func1(1, 1); });
The code show references a on the stack. That's OK when the function object doesn't outlive a. If that can't be guaranteed you may want to replace the & by = which would copy the object. BTW, the subtle change from () to {} causes the code to declare a an object of type A rather than as a function taking no argument and returning A.
unfortunately C++ doesn't have a syntax like that. A complete example with the correct syntax would look like this:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
class A
{
public:
A() {}
void Func1(int,int) {}
void Func2(long,long) {}
};
int main()
{
std::vector<std::function<void(void)>> fl;
A a;
fl.push_back(std::bind(&A::Func1, &a, 1,1));
return 0;
}
You need to provide two things (at least): 1) the pointer to member function 2) the implicit "this" pointer, i.e., the object you want to call the method on.
Then you can add the parameters you want to bind.
Note also that unfortunately you can't make an instance of "A" with "A a();" This is the "most vexing parse". The correct way is "A a;" or "A a{};"

How to ensure in run-time that a member function in an inherited class is private? (C++, gcc)

A is a base class, B is an inherited class. A takes member function pointers from B bound with boost::bind+boost::function to store and execute from other base class functions later. The A and B classes are in separate include files. I would like to restrict the developer who implements inherited classes from A that the bound member function pointers in the inherited classes are private functions. The environment is C++, gcc 4.x and Linux.
Sample:
------ INCLUDE FILE -----
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct A
{
protected:
void Register(const char* name, boost::function<void()> FuncPtr)
{
// (I am not intended to pass the name argument, but probably somebody
// knows something gcc magic which would use it to solve the problem.)
// I want to ensure that FuncPtr points to a private member
// function. What can be known: "B::CalledFunction" string and FuncPtr.
// If it is not a private member function then drop an error message
// during run-time or during compilation (???).
}
};
------ OTHER INCLUDE FILE -----
...
struct B : public A
{
B() : A()
{
Register("B::CalledFunction", boost::bind(&B::CalledFunction, this));
}
private:
void CalledFunction()
{
}
};
Any kind of macro magic or similar stuff can also be appreciated before/instead of a simple direct call to A::Register().
Rather than expand the comments, I will propose an alternative based on really using inheritance
#include <iostream>
#include <memory>
class A
{
public:
void call_a() { some_func_a(); }
private:
virtual void some_func_a() = 0; // pure virtual
};
class B : public A
{
private:
void some_func_a() { std::cout << "B::some_func_a" << std::endl; }
};
int main(void)
{
std::auto_ptr<A> a(new B);
// a->some_func_a(); // causes compiler error
a->call_a();
}
If you leave out the definition of some_func_a in B, you'll get a compiler error when you try to instantiate B.
Unfortunately, the restriction you ask for is not possible. Access restrictions are only present at compile time, not runtime; the only thing they do is control (based on lexical scope) what identifiers can be referenced.
Since the calling context producing these bound member functions obviously has access to all its member functions, you cannot distinguish between private and public member functions locally - this rules out any macro hacks. Further, member function pointers do not retain access control information (this is why you can call a pointer to a private member function from another class). As such, checking elsewhere is also not possible.
You may be able to implement this as a compiler pass in something like clang, as the information is available there at compile time; however this is not possible with a normal C++ compiler. However, this may be prone to false positives and false negatives, as the situation in which this is an issue is somewhat ill-defined (what if some derived class B really wants a bound public member function, that it'll use elsewhere?)

Misunderstanding function pointer - passing it as an argument

I want to pass a member function of class A to class B via a function pointer as argument. Please advise whether this road is leading somewhere and help me fill the pothole.
#include <iostream>
using namespace std;
class A{
public:
int dosomeA(int x){
cout<< "doing some A to "<<x <<endl;
return(0);
}
};
class B{
public:
B(int (*ptr)(int)){ptr(0);};
};
int main()
{
A a;
int (*APtr)(int)=&A::dosomeA;
B b(APtr);
return 0;
}
This brilliant piece of code leaves me with the compiler error:
cannot convert int (A::*)(int)' toint (*)(int)' in initialization
Firstly I want it to compile.
Secondly I don't want dosomeA to be STATIC.
Pointers to members are different from normal function pointers. As the compiler error indicates the type of &A::dosomeA is actually int (A::*)(int) and not int (*)(int).
Inside B's constructor you need an instance of A to call the member on using one the .* or ->* operators.
E.g'
B(int(A::*ptr)(int))
{
A atmp;
(atmp.*ptr)(int);
}
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
You don't have a pointer to a function that returns an int and takes an int. You have a pointer to a member-function that returns an int and takes an A* and an int. Not only do you need to fix the type of your pointer, B needs to provide an A* to serve as dosomeA's this parameter.
Boost::bind has some functionality meant to simplify using function pointers in general, and they provide support for pointers to member functions. See here.