2012-03-22 19 views
2

不太确定如何制定我的问题,我希望这更清楚。我想有一个基类,看起来是这样的:是否可以使用“this”从派生对象的基类发出信号

class Base : public QObject { 
    Q_OBJECT 


    void doSomething() { emit test(this); } 

    virtual void doSomethingElse() = 0; 

signals: 
    void test(Base*); 
} 

然后在派生类中做到这一点:

class Derived : public Base { 

    void doSomethingElse() { emit test(this); } 

} 

如果我现在听这个对象的信号,做我听测试(Derived *)或/和测试(Base *)?

+0

你能否具体说明“听”的意思 - 在这种情况下,很多事情都依赖于它,例如听 - 将发送者作为参数传递给slot或...? – milyaaf 2012-03-22 07:25:41

+0

通过“连接(objectInMyExample,SIGNAL(试验(基站* /派生*)),someOtherObject,SLOT(handleObject(基* /派生*))) – chikuba 2012-03-22 22:36:47

+0

确定,所以在handleObject(基*)将把手基座和连接它handlObject(导出*),它会听派生。 – milyaaf 2012-03-23 08:40:06

回答

1

商务部在编译时将基于您宣称他们在使用类的方式插槽和信号的清单宏观Q_OBJECT
这个列表是一个字符串列表,所以如果你声明:

signals: 
    void test(Base*); 

在列表中的项目将是字符串"test(Base*)"(您可以在输出目录中看到这个文件moc_yourclass.cpp的变量qt_meta_YourClass该列表)。
SIGNALSLOT也返回字符串,connect()推崇他们,使他们的格式为从商务部生成列表中的一个,并将它们与那些在该列表中。

当你派生类,串并没有改变,所以你仍然必须使用SIGNAL(test(Base*))

+0

我应该让信号虚拟吗?或者更好从基类 - >派生类而不是使用发件人并从QOBject转换到基类/派生类? – chikuba 2012-03-22 20:52:02

+0

技术上是,即使moc会给你一个警告。而且C++不支持协变或逆变参数,所以'test(Base *)'和'test(Derived *)'是无关的。您仍然可以通过虚拟函数或使用访问者模式来避免通过执行依赖于对象为“Base *”或“Derived *”的对象本身进行投射。 – alexisdm 2012-03-22 22:28:53

+0

hm。所以如果我明白你正确的话,如果我的基类中的函数是虚拟的,那么无论我是否得到一个指向Base *的指针,我都会得到虚函数等等。 – chikuba 2012-03-22 22:34:28

1

您不应该包含发件人作为信号的参数。您只需使用QObject::sender()即可获得发送信号的QObject

如:

emit test(); 

然后在一个槽:

void Listener::someObject_test() { 
    QObject* sender = QObject::sender(); 
    // or: 
    Derived* sender = (Derived*)QObject::sender(); 
} 
+1

我认为文档是安剑铮,卓杰寄件人()? – chikuba 2012-03-22 02:39:49

+0

我用了几次,从来没有任何问题的。该文件指出“此功能违反了模块化的面向对象的原则“如果你提供对象作为信号的参数,它也会违反相同的原则,有时需要知道信号来自哪里,在这种情况下,使用'QObject :: sender()'是最简单的 – 2012-03-22 03:46:49

+1

'sender()'不是空闲的,它锁定一个互斥锁并执行一个列表查找。如果你传递了这个对象作为信号的参数,它在语义上表示该对象是消息的一部分,不必使用演员使用你的对象,它也适用于信号和插槽属于不同的线程不同于'sender()'。作为奖励,你甚至可以用一个对象作为不是发送者的参数发出信号。 – alexisdm 2012-03-22 14:06:13

0

由于派生类没有自己的信号,所以您将听取测试(Base *)。

相关问题