Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt:更改QPointer时发出信号_C++_Qt_Templates_Qpointer - Fatal编程技术网

C++ Qt:更改QPointer时发出信号

C++ Qt:更改QPointer时发出信号,c++,qt,templates,qpointer,C++,Qt,Templates,Qpointer,我想创建一个类似于QPointer(或其子类)的类,每当内部指针发生变化时,该类将发出一个信号 不幸的是,我需要继承QObject类才能发出信号,而且我认为我需要使用模板才能存储特定类型的指针。但是根据我们的经验,不可能将QObject与模板混合 你知道如何让我的类跟踪内部指针的变化吗?当你想保护QObject子类实例时,你应该使用它。如果删除引用的指针,则QPointer设置为0: QLabel * label = new QLabel(); QPointer pointer = label;

我想创建一个类似于
QPointer
(或其子类)的类,每当内部指针发生变化时,该类将发出一个信号

不幸的是,我需要继承
QObject
类才能发出信号,而且我认为我需要使用模板才能存储特定类型的指针。但是根据我们的经验,不可能将
QObject
与模板混合

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

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

QLabel * label = new QLabel();
QPointer pointer = label;
delete label;
if(pointer) //false
{
//...
由于保留的对象是QObject子类,因此可以将插槽连接到其
已销毁的
信号,以跟踪其何时被删除(并且QPointer设置为零)

如果重新分配了
QPointer
,则不会发出已破坏的信号

pointer = new QLabel();
以前保存的对象仅处于未防护状态,但不会被删除

要跟踪指针重置,最好使用。 当清除或重置
QSharedPointer
Hold对象,且内部引用计数为零时,将对Hold对象调用
delete
(如果它是QObject子类,则会发出销毁信号)

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

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

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

只是提出了一个想法:创建一个继承
QObject
的类,该类只具有一个函数
emitterPointerChange
,它实际上发出一个信号,并在这个自定义发射器对象的模板类中进行合成。然后您需要将插槽连接到
MyQPointer::m_emitter
指针,而不是
QPointer
本身,这是可能的吗?同时,我发现了完全相同的解决方案:)唯一的问题是signal
reset(void*)
没有提供模板指针类型,但只有一个通用的
void*
指针。在这种情况下,将getter添加到
指针
类要比总是在参数中重新键入指针更舒服。无论如何,谢谢你的解决方案!当您访问保留的实例时,在接收到信号后,您是否100%确定它引用的是旧实例而不是新设置的实例?我将传递void指针,并使用我添加到答案中的helper方法将其强制转换。非常好的解决方案,+1
Pointer<QLabel> p;
p.connect(this, SLOT(pointerreset(void*)));
T * cast(void * p) { return static_cast<T*>(p); }
void Form::pointerreset(void * p)
{
    QLabel * label = pointer.cast(p);
    //...
}