首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt:更改QPointer时发出信号

Qt:更改QPointer时发出信号
EN

Stack Overflow用户
提问于 2018-02-28 08:45:25
回答 1查看 444关注 0票数 3

我希望创建一个类似于QPointer (或它的子类)的类,它将在内部指针被更改时发出一个信号。

不幸的是,我需要继承QObject类才能发出信号,而且我认为我需要使用模板来存储特定类型的指针。但根据这个问题,不可能将QObject与模板混为一谈。

知道如何让我的类跟踪内部指针的变化吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-28 10:07:58

当您想要保护QPointer子类实例时,应该使用。如果删除引用的指针,则QPointer设置为0

代码语言:javascript
复制
QLabel * label = new QLabel();
QPointer pointer = label;
delete label;
if(pointer) //false
{
//...

因为持有的对象是一个QObject子类,所以您可以将一个插槽连接到它的destroyed信号,以跟踪它何时被删除( QPointer设置为零)。

如果重新分配了一个QPointer,则不会发出被破坏的信号。

代码语言:javascript
复制
pointer = new QLabel();

以前持有的对象只保留不受保护,而不被删除。

要跟踪指针重置,最好使用QSharedPointer。当QSharedPointer持有的对象被清除或重置,并且内部引用计数达到零时,对所保存的对象调用delete (如果它是QObject子类,则发出被破坏的信号)。

如果您选择DIY智能指针,我建议使用QObject派生类来发射信号,并在指针类中拥有它的实例:

代码语言:javascript
复制
class Emitter : public QObject
{
    Q_OBJECT
public:
    Emitter() : QObject(0) {}
    void forward(void * p) { emit reset(p); }
signals:
    void reset(void *);
};

template <typename T>
class Pointer
{
public:
    Pointer() : instance(0){}
    void connect(QObject * receiver, const char * slot)
    {
        QObject::connect(&emitter, SIGNAL(reset(void*)), receiver, slot);
    }
    void set(T* t)
    {
        emitter.forward(instance);
        instance = t;
    }

    //...

private:
    Emitter emitter;
    T * instance;
};

显然,上面的代码是,而不是作为智能指针实现的,只是演示如何从类模板发出信号的示例。

连接插槽(例如从表单类):

代码语言:javascript
复制
Pointer<QLabel> p;
p.connect(this, SLOT(pointerreset(void*)));

传递给槽的空指针是重置前持有的T指针。为了简化不可避免的强制转换,可以向指针类添加一个助手方法,如下所示:

代码语言:javascript
复制
T * cast(void * p) { return static_cast<T*>(p); }

这样,对于一个Pointer<QLabel> pointer,在一个插槽中:

代码语言:javascript
复制
void Form::pointerreset(void * p)
{
    QLabel * label = pointer.cast(p);
    //...
}

根据智能指针实现的不同,您可以考虑根本不使用旧指针,只发出没有参数的信号。也许没有理由进一步访问旧对象,特别是当它即将被删除的时候。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49025304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档