c++ can't access object pointer from 'this' in callback function - c++

I have some strange scenario
I have object that pass to other object its 'this' pointer
like this :
void GameLayer::startGame()
{
m_pGameController = new GameController(this);
}
in the GameController constructor i set memeber with the GameLayer
GameController::GameController(GameLayer* gamelayer)
{
m_gamelayer = gamelayer;
}
in the GameController i have functions that using callback functions
like this :
GameController::methodA()
{
CurrentGem->runAction(GameController::mycallbackMethod);
}
In the callback function I access GameController functions and members with 'this'
for example:
GameController::mycallbackMethod()
{
int test = this->age();
std::string name = this->name();
}
But the problem is when I try to access the m_pGameController it gives me exception
that says its NULL pointer
GameController::mycallbackMethod()
{
this->m_gamelayer->someGamelayerMethod();
}
The error is :
Access violation reading location 0xFFFFFFFF.
What am I doing wrong ?

When passing your callback function do call like
CurrentGem->runAction(&GameController::mycallbackMethod);
Where mycallbackMethod should be static.

CurrentGem->runAction(GameController::mycallbackMethod);
make the function mycallbackMethod static.
Side note:
To call a member function by pointer, you need two things:
a pointer to the object (or object itself)
and a pointer to the function
because pointer to member function doesn't hold reall address of the function but only offset inside object. A static member function however has no this pointer, it is the same as a regular global function, except it shares the name scope of class with other class members. So in this case you don't need pointer to object to call such callback.
Instead of having static methods and passing around a pointer to the class instance, you could use functionality of std::function and std::bind.

Related

Calling class method through looping std::map

I got class called CharacterAnimation consists of one virtual method:
CharacterAnimation : public cocos2d::CCObject {
public:
...
virtual void start(float td);
}
and several inherited from it classes:
CharacterAnimationBlink
CharactedAnimationDropTear
etc
What I want is:
Create
std::map<std::string, CharacterAnimation*> animationsList;
Fill animationList like:
animationsList["blink"] = new CharacterAnimationBlink(1,2,3);
animationsList["dropTear"] = new CharacterAnimationDropTear(1,2);
Looping through this std::map
For each std::map element call
this->schedule(schedule_selector(characterAnimationStartMethodPointer), Character::animationPeriod);
What should be placed instead of currentAnimationStartMethodPointer? How do I access a pointer to start() method of current object from std::map?
From CCObject.h
typedef void (CCObject::*SEL_SCHEDULE)(float);
...
#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
Assuming that you don't control the declaration for the schedule() function, you can't get a single pointer to the start() function of a particular CharacterAnimation instance. Instead, you need two things here: a member function pointer, and a reference or pointer to the instance upon which that function should be called.
As presented in your question, it looks like schedule() demands a member function pointer (in particular, a function from the CCObject class). Your CharacterAnimation class inherits from CCObject, but a member function pointer to CharacterAnimation::start() is not a member function pointer to a CCObject function, assuming from the lack of a virtual or override specifier that start() is declared in CharacterAnimation and not inherited from CCObject.
Use this code to get the global scheduler to call the start method every Character::animationPeriod seconds.
for (std::map<std::string, CharacterAnimation*>::iterator i = animationsList.begin();
i != animationsList.end();
++i)
{
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(CharacterAnimation::start),
i->second,
Character::animationPeriod,
false);
}

cannot call member function without object error

I have a static funcA in ClassA which calls non-static funcB in classA. Although I gave object to the funcB call I still get the error: cannot call member function without object
void* ClassA::funcA(void *arg)
{
ClassA *pC = reinterpret_cast<ClassA *>(arg);
funcB(pc);
}
void* ClassA::funcB(ClassA *arg)
{
}
what is the reason for that?
A static class method can be called without an object, like you're doing.
A regular class method needs to be called on an object, like this: objectInstance.classMethod( arguments go here ) or objectPointer->classMethod( arguments go here )
Try this (after changing the signature of funcB in your class declaration to match):
void* ClassA::funcA(void *arg)
{
ClassA *pC = reinterpret_cast<ClassA *>(arg);
pC->funcB();
}
void* ClassA::funcB()
{
...
}
The problem is that to call funcB it should be done via some object like:
pC->funcB(pC);
Actually this kind of code is more like C than C++ because if you are calling a method on an object you don't need to pass it as a parameter.
You're calling from a static method, so there's no receiver object in the scope.
Consequently, you cannot call a non-static method.
You need an object, which will receive the message: o.funcB(pc);
its not a good idea to call a member function from static function , The reason why it errors out here is that the functionB is invoked from static method . the static method cannot invoke non static member functions . The reason is static function operates on classes not on objects .

C++ function pointer to a member function - which address does it receive?

Assuming I have this class:
class Shape
{
public:
int value;
Shape(int v) : value(v) {};
void draw()
{
cout << "Drawn the element with id: " << value << endl;
}
};
and the following code (which works)
Shape *myShapeObject = new Shape(22);
void (Shape::*drawpntr)();
drawpntr = &Shape::draw;
(myShapeObject ->*drawpntr)();
I have a drawpntr function pointer to a void-returning 0-arguments function member of the class Shape.
First thing I'd like to ask:
drawpntr = &Shape::draw;
the function is a member function and there's no object here.. what address does drawpntr receive? The class shouldn't even exist
I agree with the line
(myShapeObject->*drawpntr)();
because I understand I cannot de-reference a function pointer to a member function (no object -> no function), but what address is actually stored in drawpntr?? There's no object when the
drawpntr = &Shape::draw;
line is invoked.. and the class shouldn't exist either as an entity
All member functions share the same code, so they have the same address in the code segment of memory. Member functions operate on different instances only because they are implicitly passed different values of this pointer. They are not tied in any way to any of the instances on which they operate. The actual value of drawpntr could be determined statically if the function is non-virtual, or dynamically (through the vtable) if the function is virtual.

Call a Non Static Member Method from Another Method

Is there a way to call a non static class member method from another method that is contained within the main class in c++? If so, what would the code look like?
Problem is, I can't declare this specfic method as static, because it uses other methods within the same class that then don't work if I make the one static.
I'm trying to use:
MyClass::myClassMethod();
from a method within the main class, but it gives me the error: a non static member reference must be relative to a specific object.
To clarify, myClassMethod() uses other methods within MyClass like:
void myClassMethod() {
...
anotherClassMethod();
}
so if I were to make myClassMethod static it would interfere with calling anotherClassMethod().
What is the deal with calling non-static member function from a static member function?
Every non static member function is passed an this pointer implicitly in addition to the parameters you pass, the pointer passed is then dereferenced to refer class object members However static functions are not passed with the implicit thispointer and hence one cannot call any non static member function inside a static member function because there is no this to do so.
What is the solution, If you want to do it anyways?
You will need some mechanism to get the pointer to the object inside the static method and then you can call the member function using that pointer.
How to do that?
You will have to store the pointer to class object globally, or pass it as an instance in one of the function arguments to the static method.
However, both of above are workarounds, the important thing to note here is If you feel the need of calling a non static member function through a static member function then there is something wrong in your design.
On Second thoughts maybe I mis-read your Question before, Probably, Your question is:
How to call a non-static member function of a class from main?
You need a instance of the class to call non-static member functions.
So simply,
MyClass obj;
obj.myClassMethod();
And calling any other member function from within myClassMethod() would simply be:
void myClassMethod()
{
//...
anyOtherMyClassNonStaticMemberFunction();
//...
}
A static method is one that doesn't run on any particular object. It's a lot like a standalone function outside of a class, except that it's allowed to access private members in its class.
If you anotherClassMethod() is non-static, that means it has to be called on a specific object, an instance of the class. Because it's called on an object, it can access data stored in that object (non-static member variables). If myClassMethod() is static and you implement it as
void MyClass::myClassMethod() {
anotherClassMethod();
}
That won't work because anotherClassMethod() expects to be called on a specific object, but myClassMethod() doesn't have one. But if you know what object you want to call it on, you can do it as an ordinary method call on an object:
void MyClass::myClassMethod(MyClass &object) {
object.anotherClassMethod();
}
The object doesn't have to be passed in as an argument; it could be a static member variable in the class, for example:
class MyClass {
private:
static MyClass theInstance;
// ...
};
void MyClass::myClassMethod() {
theInstance.anotherClassMethod();
}
Ultimately, the question you need to ask yourself is: why is myClassMethod() static, and why is anotherClassMethod() non-static? Take a step back, think about what myClassMethod() is supposed to do. Does it make sense to call it when you don't have an instance to work with? If so, why does it need to call a method that expects to work with an instance?
The only way to call a non static method of a class is through an instance of that class. So you would need something like this...
MyClass myClass;
myClass.myClassMethod();
I think that maybe you could use the singleton pattern, keep a instance of the class in global. like a utility class.

Error while calling function

I am getting an error when I call one static function of a class in to any other function (means by non-class function), then it is giving following error:
undefined reference to function name_function.
Can any one tell me why this is happing?
Basic C++: A non-static member function assumes that it has access to an object of the class type (it can refer to the member variables directly and the "this" pointer points to the object).
This means that you can't call a non-static member function unless you have an object of that type. In a static member function, you don't.
(I'm not 100% sure this is an answer to your question, as it's not clean from your explanation if you tried to call a non-static function from a static one, or vise versa.)
Are you prepending the class name before the function name?
so, if you have:
class MyClass
{
...
public static function name_function() { ... }
...
}
you need to call this function like this:
MyClass::name_function();