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)();
Related
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.
#include <iostream>
using namespace std;
class temp
{
public:
temp()
{
std::cout << "Constructor created." << std::endl;
}
~temp()
{
std::cout << "Deconstructor called." << std::endl;
}
};
class scopedptr
{
private:
temp* ptr;
public:
scopedptr(temp* p)
{
ptr = p;
std::cout << "scoped" << std::endl;
}
~scopedptr()
{
delete ptr;
}
};
int main()
{
{
scopedptr a = new temp();
}
}
Most of the code above is not relevant but I wrote it so that there is a background to my question.
My question resides inside the main function, I know the line "scopedptr a = new temp();" will work, my doubt is the what is happening with the object a, is it associated with the class scopedptr or the temp class.
This code does not have many variables but what if there are multiple variables inside both the classes, will object a be able to call methods from class scopedptr or class temp or both.
I'm literally confused, what's happening with the object? which class is its type???
In the line
scopedptr a = new temp();
type of a is explicitly specified as scopedptr. Any usage of a must correspond to the type scopedptr.
When in doubt, simplify.
temp* temp_ptr = new temp();
scopedptr a{temp_ptr};
Then, there is less scope for confusion.
a is a scopedptr with an owning pointer to a temp.
will object a be able to call methods from class scopedptr or class temp or both
To be able to treat it as a smart pointer, you'd usually add member functions, deferencing the owned pointer:
class scopedptr {
public:
temp* operator->() { return ptr; }
temp& operator*() { return *ptr; }
};
You can now do a->func(); to call a function in the temp object.
Also look into the Rule of 5 for safe handling of the owned pointer.
Demo
So, what i'm trying to do is this:
I would like to create a general class MyCLASS with a function genericFunction() which is empty by default. Now, when a co-worker wants to use this generic function, what he does is creating an instance of MyClass, and overriding genericFunction(), so it should give a resoult similar to this:
class MyClass{
public:
void genericFunction(){
//boring default actions
}
//constructor
MyClass(){
//do things
}
};
int main(){
MyClass instance();
//now we override the function, something like:
instance.genericFunction(){
cout << "This new code exists only for this instance, and has been created outside the class!";
}
instance.genericFunction();
return 0;
}
So that's basically what I would like to do.
In the case that it is not possible, how can i make my class run a function that is going to be later defined in main()?
Thanks a lot!
EDIT: To answer your questions:
*I'm new to c++ and it's true that my background is from other languages
*The idea is the following: You are creating objects that have a position, and if the position is in a certain range, genericFunction() is executed. The thing is that for each instance the function that is executed may (or in fact should) be different. The idea is 'inspired' by android's clickListener, where each element has a different function to execute when clicked
Thanks again!
If you want to be able to set user defined functions for a class object then you can give it a member variable of type std::function. Using slightly different syntax from your example it could look like this:
class MyClass
{
public:
std::function<void()> genericFunction = []{};
};
int main()
{
MyClass instance;
instance.genericFunction(); // does nothing
// assign a lambda function to our
// function member
instance.genericFunction = []
{
std::cout
<< "This new code exists only for this instance, and has been created outside the class!";
};
instance.genericFunction(); // executes our lambda function
}
EDIT
If you want to be able to pass parameters or receive a return value, then change the template signature to std::function like this:
class MyClass
{
public:
// take a string parameter and return an integer
std::function<int(std::string const&)> genericFunction = [](std::string const&){ return 0; };
};
int main()
{
MyClass instance;
int return_value;
return_value = instance.genericFunction("This will do nothing and return 0"); // does nothing
std::cout << "The first function returned: " << return_value << '\n';
// assign a lambda function to our
// function member
instance.genericFunction = [](std::string const& msg)
{
std::cout << msg << '\n';
return 5;
};
return_value = instance.genericFunction("This will pint a message and return 5"); // executes our lambda function
std::cout << "The second function returned: " << return_value << '\n';
}
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;
}