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
本身,这是可能的吗?同时,我发现了完全相同的解决方案:)唯一的问题是signalreset(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);
//...
}