Reputation: 179
I need the pointer to the specific object, that calls the method I'm in to compare the calling objects type to a specific type.
Here I cannot do it by using parent() and i cannot use sender() because the method is not called via signal/slot. Also it would take too much effort to pass the pointer as an argument because the "target" method is used by many classes and sometimes it's even used as a slot.
I need this for a big existing code so it's not a viable option to change the software structure. Sadly i have to deal with the software as it is.
void ClassA::callingFunction()
{
AnyObject *obj = new AnyObject();
obj->desiredMethod();
}
void ClassB::callingFunction()
{
AnyObject *obj = new AnyObject();
obj->desiredMethod();
}
void AnyObject::desiredMethod()
{
QObject *callingObject = ?
//Here i need a pointer to the instance of ClassA/ClassB which calls this method
bool bTypeMatch = typeid(*callingObject) == typeid(ClassA);
if(bTypeMatch) {...}
}
Upvotes: 0
Views: 549
Reputation: 98435
This would be perhaps the only time where you have truly no choice but to call on the preprocessor to help you out. The desiredMethod
is defined to be a fully qualified name, so that if the same method name is used elsewhere, it shouldn't compile and you'll be aware of the problem rather than facing possibly silent corruption of unrelated code.
Since desiredMethod
is called with an argument of correct type, there's no reason to do any manual type casting. Instead, overload on the types you want to handle. If you want a default handler, you can implement desiredMethod(QObject * o)
: it'll catch all calls not handled by more specific overloads, since QObject
is a base class of all the derived types you intend to handle.
#include <QtCore>
struct ClassA;
struct ClassB;
static enum { NONE, A, B } from = NONE;
struct AnyObject {
void desiredMethod(ClassA *) { from = A; }
void desiredMethod(ClassB *) { from = B; }
};
#define desiredMethod() ::AnyObject::desiredMethod(this)
struct ClassA : public QObject {
void callingFunction() { AnyObject().desiredMethod(); }
};
struct ClassB : public QObject {
void callingFunction() { AnyObject().desiredMethod(); }
};
int main() {
ClassA a;
ClassB b;
Q_ASSERT(from == NONE);
a.callingFunction();
Q_ASSERT(from == A);
b.callingFunction();
Q_ASSERT(from == B);
}
Upvotes: 0
Reputation: 37927
from question:
Also it would take too much effort to pass the pointer as an argument because the "target" method is used by many classes and sometimes it's even used as a slot.
So add default value for argument or provide overloaded version so you could update code only in needed places.
So improving answer from @TheDarkKnight IMO this could look like this:
void AnyObject::desiredMethod()
{
desiredMethod(NULL); //nullptr in C++ 11
}
void AnyObject::desiredMethod(ClassA* callingClassPtr) // not casting is not needed
{
if(callingClassPtr)
{
// extra action
}
}
Upvotes: 0
Reputation: 27611
Pass in the ptr to the calling object and you can dynamic_cast
to check its type
void AnyObject::desiredMethod(QObject* callingClassPtr)
{
ClassA* aPtr = dynamic_cast<ClassA*>(callingClassPtr);
if(aPtr != nullptr) //nullptr in C++ 11
{
// I'm of type ClassA*
}
}
Other than this, there is no other way of achieving your goal.
Upvotes: 1
Reputation: 2462
you can pass pointer of caller as QObject *
and then either:
QObject::metaObject()->className()
qobject_cast
Q_CLASSINFO
and check against itOf course, to make it work you need either QObject
-derived caller classes, or pointers to QObject
.
Only thing i'm sure about is that you'll not be able to get pointer to caller from direct function call without sender parameters
Upvotes: 1