如何获取指向调用 (Q)Object 的方法的指针

How can i get a pointer to the method calling (Q)Object?

本文关键字:Object 方法 指针 何获 取指 调用      更新时间:2023-10-16

我需要指向特定对象的指针,该指针调用我所在的方法以将调用对象类型与特定类型进行比较。

在这里,我无法使用 parent() 来做到这一点,也不能使用 sender(),因为该方法不是通过信号/插槽调用的。此外,将指针作为参数传递需要花费太多精力,因为"target"方法被许多类使用,有时它甚至用作插槽。

我需要它来存储大型现有代码,因此更改软件结构不是一个可行的选择。可悲的是,我必须按原样处理软件。

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) {...}
}

您可以将调用方的指针作为QObject *传递,然后:

  1. 使用QObject::metaObject()->className()检查类型名称
  2. 检查对象是否按qobject_cast强制转换为所需类型
  3. 设置其他类元信息宽度Q_CLASSINFO并对其进行检查

当然,要使其正常工作,您需要QObject派生的调用方类或指向QObject的指针。

我唯一确定的是,如果没有发送方参数,您将无法从直接函数调用中获取指向调用者的指针

将 ptr 传递给调用对象,您可以dynamic_cast检查其类型

void AnyObject::desiredMethod(QObject* callingClassPtr)
{    
    ClassA* aPtr = dynamic_cast<ClassA*>(callingClassPtr);
    if(aPtr != nullptr) //nullptr in C++ 11
    {
        // I'm of type ClassA*
    }
}

除此之外,没有其他方法可以实现您的目标。

来自问题:

此外,将

指针作为参数传递也需要太多精力 因为"目标"方法被许多类使用,有时它是 甚至用作插槽。

因此,为参数添加默认值或提供重载版本,以便您只能在需要的地方更新代码。

因此,从IMO@TheDarkKnight改进答案,这可能看起来像这样:

void AnyObject::desiredMethod()
{
    desiredMethod(NULL);  //nullptr in C++ 11
}
void AnyObject::desiredMethod(ClassA* callingClassPtr) // not casting is not needed
{    
    if(callingClassPtr)
    {
         // extra action
    }
}

这可能是您唯一一次真正别无选择,只能求助于预处理器来帮助您。desiredMethod被定义为完全限定的名称,因此,如果在其他地方使用相同的方法名称,则不应编译它,并且您将意识到问题,而不是面对不相关代码的可能无提示损坏。

由于desiredMethod是使用正确类型的参数调用的,因此没有理由进行任何手动类型转换。相反,对要处理的类型进行重载。如果你想要一个默认处理程序,你可以实现desiredMethod(QObject * o):它将捕获所有未由更具体的重载处理的调用,因为QObject是你打算处理的所有派生类型的基类。

#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);
}