如何获得指向调用(Q)对象的方法的指针?

时间:2016-04-26 09:49:10

标签: c++ qt

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

这里我不能通过使用 parent()来实现它,我不能使用 sender(),因为该方法不是通过signal / slot调用的。此外,将指针作为参数传递需要花费太多精力,因为" 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) {...}
}

4 个答案:

答案 0 :(得分:1)

将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*
    }
}

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

答案 1 :(得分:1)

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

  1. 使用QObject::metaObject()->className()
  2. 检查类型名称
  3. 检查对象是否按qobject_cast
  4. 转换为所需类型
  5. 设置其他类元信息宽度Q_CLASSINFO并对其进行检查
  6. 当然,要使其工作,您需要QObject - 派生的调用者类或指向QObject的指针。

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

答案 2 :(得分:0)

来自问题:

  

将指针作为参数传递也需要花费太多精力   因为“目标”方法被许多类使用,有时候也是如此   甚至用作插槽。

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

所以改善@TheDarkKnight IMO的答案,这可能是这样的:

void AnyObject::desiredMethod()
{
    desiredMethod(NULL);  //nullptr in C++ 11
}

void AnyObject::desiredMethod(ClassA* callingClassPtr) // not casting is not needed
{    
    if(callingClassPtr)
    {
         // extra action
    }
}

答案 3 :(得分:0)

这可能是你真正别无选择只能拜访预处理器来帮助你的时候。 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);
}