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.
Related
I'm testing, trying to call a member function being passed as a parameter,
the member function has to be one of another class.
this is an example, which gives an error:
"pointer-to-member selection class types are incompatible ("B" and
"A")"
This is the code, what am I doing wrong?
#include <iostream>
using namespace std;
class A {
private:
public:
void fA(int x) {
cout << "hello" << endl;
}
void fB(int x) {
cout << "good bye" << endl;
}
A() {
}
};
class B {
private:
void (A:: * f)(int) = NULL;
public:
B(void (A:: * f)(int)) {
this->f = f;
}
void call() {
(this->*f)(10); //What's wrong here?
}
};
A a = A();
B b = B(&(a.fA));
B b2 = B(&(a.fB));
int main(void) {
b.call();
b2.call();
}
&(a.fA) is not legal C++ syntax. &A::fA is. As you can see, there is no object of type A anywhere of this syntax. &A::fA is just a pointer to a member function, not a pointer-to-member-together-with-an-object combo.
Now in order to call that pointer-to-member, you need an object of class A. In class B, you don't have any. You need to get one in there somehow, and call the function this way:
(a->*f)(10);
where a is a pointer to that object of class A.
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;
}
can you please explain me why this code shows nothing except for the last std::cout line in main()? Checked through similar threads on stackoverflow.com, was not able to connect them to mine, is this pointing legal at all? I try to set a function pointer of a class to another class function:
#include <iostream>
class container;
class one {
public:
one()
{
eventsHandler = NULL;
};
~one() {};
void (container::*eventsHandler)();
};
class container {
public:
container()
{
zone = new one;
zone->eventsHandler = &container::events;
};
~container()
{
delete zone;
};
one *zone;
void events()
{
std::cout << "event handler is on..." << std::endl;
};
};
int main()
{
container *test = new container;
test->zone->eventsHandler;
std::cout << "just checker..." << std::endl;
delete test;
system("pause");
};
You should use operator->* for calling the member function pointer, and assign test as the object which will be called on,
(test->*test->zone->eventsHandler)();
or more clear,
(test->*(test->zone->eventsHandler))();
LIVE
You need to provide an object to call a pointer to memeber function:
container *test = new container;
(test->*test->zone->eventsHandler)();
Here, test is the object, test->zone->eventsHandler is the pointer to member function that you have saved, and operator->* joins them.
So, it is very much like any other member function; however, you can switch which objects to call a member on:
container *first = new container;
container *second = new container;
(first->*second->zone->eventsHandler)();
// both pointers point to the same function
std::cout << (first->zone->eventsHandler == second->zone->eventsHandler) << std::endl;
You have to actually call the function pointer, in line 38, as:
(test->*test->zone->eventsHandler)();
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;
}
I want to define a member function in class and use its pointer. I know that I can use static member function but the problem with it is that I can only access the static members of the class. Is there a way other than static member function to be able to get function pointer.
To be more specific: There is a library which I'm using which gets a function pointer as its input. I want to write a member function and assign its function pointer to that external library. Should I create an object of class or use this pointer to do this?
You can get the pointer of the method, but it has to be called with an object
typedef void (T::*MethodPtr) ();
MethodPtr method = &T::MethodA;
T *obj = new T();
obj->*method();
If you need to have non-object pointer and you want to use object then you have to store instance of object somewhere, but you are restricted to use only one object (singleton).
class T {
static T *instance;
public:
T::T() {
instance = this;
}
static void func() {
instance->doStuff();
}
void doStuff() {}
};
If library supports user data for function pointers, then you may have multiple instances
class T {
public:
static void func(void *instance) {
((T*)instance)->doStuff();
}
void doStuff() {}
};
If:
you want to get the function pointer of a nonstatic member from within the class
And use it within the class:
Then:
It can work, because when you get the member function address, there is a "this" pointer. The syntax was not obvious to me, and it may look somewhat ugly, but not TOO bad.
This may not be new to the true experts, but I have wanted to have this in my bag of tricks for a long time.
Here is a complete sample program:
#include <iostream>
class CTestFncPtr
{
public:
CTestFncPtr(int data) : mData(data)
{
// Switch = &CTestFncPtr::SwitchC; // Won't compile - wrong function prototype - this is type safe
if (data == 1)
Switch = &CTestFncPtr::SwitchA;
else
Switch = &CTestFncPtr::SwitchB;
}
void CallSwitch(char *charData)
{
(this->*Switch)(charData);
}
private:
void SwitchA(char * charData)
{
std::cout << "Called Switch A " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
Switch = &CTestFncPtr::SwitchB;
}
void SwitchB(char * charData)
{
std::cout << "Called Switch B " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
Switch = &CTestFncPtr::SwitchA;
}
void SwitchC()
{
}
void(CTestFncPtr::*Switch)(char * charData);
int mData;
};
int main(int argc, char * argv[])
{
CTestFncPtr item1(1);
item1.CallSwitch("Item1");
item1.CallSwitch("Switched call Item 1");
CTestFncPtr item2(0);
item2.CallSwitch("Item2");
item2.CallSwitch("Switched call Item 2");
return 0;
}