vector of call back functions and function pointer binding - c++

I am new to the std::function and trying to implement a callback function. In the following code "Callback_t" contains a function that holds a vector of function to be called. Class "other" is a nested class inside "SomeClass". An object of "SomeClass" contains an array of nested class object "b". The "other" class constructor assigns a function pointer to "fptr". I push this function in to the vector of callback class "Callback_t". When I run this code, I get the segmentation fault when the first function in the vector is invoked. I am not able to figure out what is wrong with the statement
this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);
However if I replace it with
this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))
the code works perfectly. I need help to understand what's wrong with the original statement.
#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(void)> func_type;
class Callback_t {
public:
std::vector<func_type> set_of_cb;
void myCallback()
{
for (int i = 0; i < set_of_cb.size(); i ++){
set_of_cb[i]();
}
}
};
class SomeClass;
class SomeClass {
private:
Callback_t *loc_ptr;
int a[10];
class other{
public:
int id;
SomeClass *loc;
func_type fptr;
other(){};
other(SomeClass *loc, int id){
this->id = id;
this->loc =loc;
fptr = std::bind(&other::func,this);
}
void func(void){
this->loc->a[id] = loc->a[id] * id;
return;
}
};
public:
other *b;
//other b[10];
SomeClass(Callback_t *a = nullptr){
this->loc_ptr = a;
this->b = new other[10];
for(int i =0; i <10;i++){
this->a[i] = i;
this->b[i] = other(this, i);
this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);
}
}
void read(void){
for(int i =0; i <10;i++){
std::cout<<a[i]<<std::endl;
}
}
};
int main()
{
Callback_t *tmp;
tmp = new Callback_t;
SomeClass tmp1(tmp);
tmp1.read();
tmp->myCallback();
tmp1.read();
delete tmp;
}

other(SomeClass *loc, int id){
this->id = id;
this->loc =loc;
fptr = std::bind(&other::func,this);
}
The constructor binds fptr to this, which is the constructed object. Now, pay careful attention:
this->b[i] = other(this, i);
This performs the following sequence of events. There are quite a few things happening here, that are crucial to this mystery:
A temporary other object gets constructed, and its constructor does what it does. Note that the object is temporary, so its constructor ends up binding its fptr to a temporary object! You're beginning to see the problem, but let's close the loop, anyway:
The object gets assigned to this->b[i]. This is effectively a copy.
The original temporary objects gets destroyed.
The end result is that b[i]'s bound function ends up getting bound to a temporary object that is now destroyed. This results in undefined behavior and your crash.
And with your working alternative:
this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))
You are binding the std::function to a valid instance of the object, in b[i].
That's it.

The other answer explains what is going wrong in your code. What is left to do is to show case a more canonical example of achieving what you go for (with a little help from lambda functions). Of course, std::bind() also works, but it is pre C++11 and I think nowadays most would rather do it as I do in my code below.
#include <iostream>
#include <functional>
#include <vector>
class Foo {
public:
void FooFun() {
std::cout << "Foo::FooFun() called" << std::endl;
}
};
class Bar {
public:
void BarFun() {
std::cout << "Bar::BarFun() called" << std::endl;
}
};
using CallbackFun_t = std::function<void()>;
using Callbacks_t = std::vector<CallbackFun_t>;
int main(int argc, const char * argv[]) {
Foo foo{};
Bar bar{};
Callbacks_t callbacks
{ [&foo]{ foo.FooFun();}
, [&bar]{ bar.BarFun();}
};
for( auto& cb : callbacks ) {
cb();
}
return 0;
}

Related

How to queue up methods to run until a limit is reached

So I have a bunch of objects (subclasses of a parent class) with various functions each having different names, I might not have the resources to run all of the functions for each object so I want to have them in a priority list to run over time.
The code bellow is I believe forbidden by c++.
I get "C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function"
class A;
class Token;
list<Token> tokenList;
class Token{
public:
A* a; //Could be A or a child of A
int* function;
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello;
tokenList.push_back(token);
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
The code bellow should work but doesn't look elegant and also doesn't support subclasses having multiple functions they could pass to the list, is there a better way to do this I am missing?
class A;
list<A*> aList;
class A {
public:
virtual int funct();
};
class B : public A{
public:
virtual int funct(){
hello();
return 0;
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
int main(){
//remove objects from list and run their functions in a loop until list is empty or max number of functions were run
Thanks Ted
Solution: Using the first example as mentioned I changed int* function; to int (A::*function)();. Then I can run the function with something like this
A tmp = A();
Token token = *tokenList.begin();
A *a = token.a;
(a->*token.function)();
}
The problem is that in your code int* function; is a pointer to an integer and not a pointer to a function.
If you would define it as int (*function)(); you could easily do what you want. But it would still not work with member functions.
So you need to define it as a pointer to a member function: int (A::*function)();
Here an example to make it work:
class Token{
public:
A* a; //Could be A or a child of A
int (A::*function)(); // pointer to member function with no arg, returning int
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello; // Use the address of member function
tokenList.push_back(token);
}
int hello(){
cout << "hello (" << this <<")"<< endl; // added the address of a to see for which object
return 0;
}
};
int main() {
A a;
A b;
for (auto& token : tokenList )
(token.a->*token.function)(); // invoke the member function on the object pointer
}
Online demo
I didn't notice that your tokenList was a global variable. This is rather risky, as everything you create an A (including a temporary one), the tokenList will be updated. When you'll execute it, you'll therefore risk of having dangling pointers, i.e. pointing to an A instance that has already destroyed.

Creating Smart pointer of the object itself (this) in its constructor

So lets say I have
class A
{
A(std::vector<std::shared_pointer<A>> &a_vec)
{
auto shared_ptr = std::make_shared<A>(*this);
a_vec.pushback<shared_ptr>;
{
};
class B
{
std::vector<std::shared_pointer<A>> a_vector_;
void constructA()
{
created_A = make_shared<A>(a_vector_);
}
}
So Im creating a method for B which creates an A and the A pushes itself to the vector B provides.
And on paper this dependancy works like I expected to, atleast I thought it was until I realised the a_vec.pushback<this*>; is not very dependable.
When I have more code inbetween the push and the shared pointer initialisation as such
A(std::vector<std::shared_pointer<A>> a_vec)
{
auto shared_ptr = std::make_shared<A>(*this);
//insert more code here
a_vec.pushback<shared_ptr>;
{
It seems that the initialisations and other stuff I do in there isn't reflected to the pointer the shared pointer is pointing. Whats the cause of this and is there a way to fix it? Also is there a reason this would be a bad practice to use?
One of the challenges when you are programming in C++ is to understand object lifetime. So it is better to make object creation and destruction as clear as possible.
As I understood your case is to memoize "automagically" all created objects. It is easier to do using "factory method" constructA
#include <iostream>
#include <vector>
#include <memory>
class A
{
public:
A() = default;
};
class B//AInstanceFactory - is a better name
{
std::vector<std::shared_ptr<A>> a_instances;
public:
void constructA()
{
a_instances.push_back(std::make_shared<A>());
}
const std::vector<std::shared_ptr<A>>& getAInstances() {
return a_instances;
}
};
int main()
{
B b;
b.constructA();
std::cout << b.getAInstances().size() << "\n";
b.constructA();
std::cout << b.getAInstances().size() << "\n";
}
[WRONG PATH]
It is possible to make object which aware of shared_ptr/weak_ptr: use template std::enable_shared_from_this.
In that case your code might be following,:
#include <iostream>
#include <vector>
#include <memory>
class A : std::enable_shared_from_this<A>
{
public:
A(std::vector<std::shared_ptr<A>>& a_vec)
{
a_vec.push_back(shared_from_this());//bad_weak_ptr here!!!!
}
};
class B
{
std::vector<std::shared_ptr<A>> a_vector_;
public:
void constructA()
{
auto a_ptr = make_shared<A>(a_vector_);
}
const std::vector<std::shared_ptr<A>>& getAVec() {
return a_vector_;
}
};
int main()
{
B b;
b.constructA();
std::cout << b.getAVec().size() << "\n";
}
BUT it wrong, because underlying weak_ptr is "ready" only after function make_shared is executed, means only after construction call.
Calling shared_from_this or weak_from_this is valid only after make_shared function is executed.

Create object after ID is allocated in std::unordered_map

I have an std::unordered_map which stores an integer with an object. Here's some code for you to understand:
#include <iostream>
#include <unordered_map>
#include <cstdlib>
using namespace std;
class Foo
{
public:
Foo()
{
cout << "Foo created!" << endl;
}
~Foo()
{
}
};
typedef std::unordered_map<int, Foo*> FooMap;
FooMap fm;
int allocateID()
{
cout << "Allocating ID" << endl;
return rand() % 100;
}
void add()
{
fm.emplace(allocateID(), new Foo());
}
int main()
{
srand(time(NULL));
add();
return 0;
}
Output:
Foo created!
Allocating ID
The problem here is that the object Foo is created before an ID is allocated! I tried adding a mutex lock on allocateID; it didn't work because allocateID() runs AFTER the object is created.
How can I modify this program such that Foo is created AFTER the ID is allocated?
EDIT:
I've played around with the code and used a solution herein to demonstrate:
void add(int id, Foo *f)
{
auto iden = id;
auto foo = f;
fm[iden] = foo;
}
void add(Foo *f, int id)
{
auto iden = id;
auto foo = f;
fm[iden] = foo;
}
void add()
{
int id = allocateID();
fm[id] = new Foo();
}
In the first add() function, the output remains the same. This doesn't solve the problem.
In the second add() function, the output is different, instead producing:
Allocating ID
Foo created!
And in the third function, it has been modified with one of the solutions: this function also produces the desired output. The problem with the third function is that it's highly unlikely there would be an empty add() function realistically. The only culpable way of solving this issue is to pass the object first AND THEN the id. This is probably because the arguments are read from right to left, regardless of the entry requirements because they are created after the arguments are read anyway.
You can't rely on order of evaluation of function arguments. Try this:
void add()
{
int temp = allocateID();
fm.emplace(temp, new Foo());
}
Unless you are absolutely sure how the compiler will interpret your code, you don't want to rely on it and let it tell you what you wanted to do. Since you are having problems you should force the compiler to create the id first as such:
void add()
{
int id = allocateID();
fm[id] = new Foo();
}
This will fix your problems.

C++ Function Pointer as Argument and Classes?

Hmm I'm reading some guides on this but I can't figure this out, how do I properly use function pointers in C++?
I have a class that I want to call a function after it has finished whatever it is doing at the moment, like this:
class WindowImages
{
public:
void Update()
{
for(unsigned int i = 0; i < _images.size(); i++)
{
//Do something
_images[i]->MyFunctionPointer();
}
}
void Add(Image* image, void (*func)(void))
{
image->function = func; //this is wrong
_images.push_back(image);
}
private:
vector<Image*> _images;
}
class Image
{
public:
void ImageClicked();
void *function(void);
};
void main()
{
Image* image = new Image();
WindowImages images;
images.Add(image, image->ImageClicked);
}
I'm trying to add the image to the vector, and pass a function as argument that will be called when the images class finish doing whatever it has to do with each image.
The functions will be different per image but they'll all be in the void function() format.
I've been trying a bunch of things but got nothing so far, how can I do this?
Also, if you happen to have a more... beginner friendly tutorial or guide on function pointers (and even maybe C++ 11 lambdas) that'd be really helpful!
You're not using a regular function pointer for your callback. You're using a non-static member function pointer, so the regular function pointer syntax and calling mechanics aren't going to work. There is a significant difference both in the pointer declaration syntax and the mechanism used for invoking non-static members.
To declare a pointer-to-member function for a member of the Image class taking no parameters and returning void, the syntax would be:
void (Image::*function)().
Invoking a member function is done using one of two special operators, ->* when using an object pointer, or .* when using an object reference. For example:
// declare a pointer to Image member function
void (Image::*function)();
// assign address of member function
function = &Image::ImageClicked;
// uses ->* for access
Image *pObj = new Image();
(pObj->*function)();
// uses .* for access
Image image;
(image.*function)();
Hope that helps
First of all, I think your intention is better done via C++ polymorphism, though which is done by function pointer underhood. C++ function pointer tutorial
The following code does what you want to do.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
void f1() {
cout << "f1()" << endl;
}
void f2() {
cout << "f2()" << endl;
}
void f3() {
cout << "f3()" << endl;
}
class A {
public:
void (*fp)();
};
class B {
public:
void add(A* a, void (*fp)()) {
a->fp = fp;
vec_a.push_back(a);
}
~B() {
for (int i = 0; i < vec_a.size(); ++i) {
vec_a[i]->fp();
}
}
private:
vector<A*> vec_a;
};
int main() {
B *b = new B();
A* a[3];
a[0] = new A();
a[1] = new A();
a[2] = new A();
b->add(a[0], f1);
b->add(a[1], f2);
b->add(a[2], f3);
delete b;
}
The output is
f1()
f2()
f3()
First and foremost, I suggest against using function pointers in C++. In general, the same functionality can and should be achieved using virtual classes.
When working with function pointers, I find typedefs to be really useful to keep things organized. This somewhat contrived example accomplishes roughly what you are trying to do...
#include <stdio.h>
#include <vector>
typedef void (*fptr_type) (int);
void printSquare (int i) {
printf ("%d\n", i * i);
return;
}
void printDouble (int i) {
printf ("%d\n", 2 * i);
return;
}
class IntFPtrClass {
public:
int intVal;
fptr_type fptr;
IntFPtrClass (int i, fptr_type f) : intVal(i), fptr(f) { }
// Just to show that static methods can be used as function pointers.
static void printPlusOne(int i) {
printf ("%d\n", i + 1);
return;
}
};
int main (void)
{
std::vector<IntFPtrClass> my_vector;
my_vector.push_back (IntFPtrClass(3, printSquare));
my_vector.push_back (IntFPtrClass(5, printDouble));
my_vector.push_back (IntFPtrClass(7, IntFPtrClass::printPlusOne));
for (int i = 0; i < my_vector.size(); ++i)
{
my_vector[i].fptr(my_vector[i].intVal);
}
return 0;
}

Using pointers in class over multiple functions C++

So I have 2 functions and 1 class.
with 1 function I want to Set value's of the integers stored in a class.
with the other function I want to use these value's again.
I'm using pointers as I thought this would be saved on Memory address's across the whole program.
#include <iostream>
using namespace std;
void Function1();
void Function2();
class TestClass
{
public:
TestClass();
~TestClass();
void SetValue(int localValue)
{
*value = localvalue;
}
int GetValue()const
{
return *value;
}
private:
*value;
};
TestClass::TestClass()
{
value = new int(0);
}
TestClass:
~TestClass()
{
delete value;
}
int main()
{
TestClass *tommy = new TestClass; //this didn't work,
//couldn't use SetValue or Getvalue in functions
Function1();
Function2();
return 0;
}
void Function1()
{
int randomvalue = 2;
TestClass *tommy = new TestClass; //because it didnt work in main, i've put it here
tommy->SetValue(randomvalue);
}
void Function2()
{
TestClass *tommy = new TestClass;
cout << tommy->GetValue();
<< endl; //this gave a error, so I put the above in again
//but this returns 0, so the value isn't changed
}
So, got a solution for me? I didn't got any compile errors, but the value isn't changed, probably because the destructor is called after Function1 has been completed. so how do I do it?
You need to pass your tommy from main() to each of your functions, not create a new one in each time, otherwise you're just losing the new Testclass objects you're creating in your functions, and actually here getting memory leaks because you use new.
Something like:
void Function1(TestClass * tommy) {
int randomvalue =2;
tommy->SetValue(randomvalue);
}
and then in main():
int main() {
TestClass *tommy = new TestClass;
Function1(tommy);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
This is an odd use case, though - this would be the kind of thing you'd expect member functions to do. This would be better:
int main() {
TestClass *tommy = new TestClass;
tommy->SetValue(2);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
without the need for Function1() and Function2(). Either way, you're going to have to fix:
private:
*value;
in your class, as someone else pointed out.
you are not passing your TestClass to either function so they functions can't see the tommy object you made. Then in each function you create a new local variable that just happens to have the same name as your local variable in main... They are all independent objects
Every time you write new TestClass, you are quite literally creating a new instance of a TestClass object. The new instance is not related to any existing instances in any way, except for being of the same type. To make the single instance of TestClass be "the one" being used by your functions, you need to pass it in as an argument to those functions.
Also -- Don't use pointers unless it is absolutely necessary.
Here's a cleaned up example of your code that accomplishes what it appears you were trying.
class TestClass
{
int value;
public:
TestClass() : value(0)
{}
int GetValue() const { return value; }
void SetValue(int x) { value = x; }
};
// takes a "reference", works somewhat like a pointer but with
// some additional safety guarantees (most likely will not be null)
// This will modify the original passed in TestClass instance.
void SetRandomValue(TestClass& tc)
{
int random = 2; // not really random...
tc.SetValue(random);
}
// take a const reference, similar to above comment, but a const
// reference cannot be modified in this scope
void Print(const TestClass& tc)
{
std::cout << tc.GetValue() << "\n";
}
int main()
{
// create a TestClass instance with automatic storage duration
// no need to use a pointer, or dynamic allocation
TestClass tc;
// Modify the instance (using reference)
SetRandomValue(tc);
// print the instance (using const reference)
Print(tc);
return 0;
}