3

(C++/Qt) 我有一个指向 QObject 的智能指针。假设是 QWeakPointer。由于某些外部原因(可能在另一个对象中发生的事情或由于某个事件),指向的对象可能会被破坏。因为我有一个智能指针,所以不会有悬空引用,所以没有问题。但我总是要检查指针是否为空。

我正在考虑使用空模式以避免一直检查这一点,但我不确定这对于 QObject 是否可行或方便。这个想法是指针指向对象,如果它被破坏,智能指针会将其指向的对象更改为空对象。这是一个好主意还是我应该忘记它并检查指针是否一直为 NULL?


让我们给你看一个例子。我们有一个工人使用工具来完成工作:

class Worker : public QObject
{
    Q_OBJECT

public:
    Worker(QObject *parent = 0);
    void work()
    {
        if(m_tool)
            m_tool->use();
        emit workCompleted();
    };

signals:
    workCompleted();

public slots:
    void setTool(QWeakPointer<Tool> tool);

private:
    QWeakPointer<Tool> m_tool;
};


class Tool : public QObject
{
    Q_OBJECT

public:
    Tool();

public slots:
    void use() =0;
};


class Screwdriver : public Tool
{
    Q_OBJECT

public:
    Screwdriver() : Tool();

public slots:
    void use()
    {
        // do something
    };
};


class Hammer : public Tool;
class Saw : public Tool;
...

在这种情况下,工具是一个库的公共领域对象,由 Worker 使用。我正在开发这样的库。所以工人正在使用螺丝刀,但它被打破并被摧毁。没问题:

if(m_tool)
    m_tool->use();
emit workCompleted();

m_tool 为 0,所以它什么也不做。但是我们必须每次都检查它是否不为空。

现在假设我们有一个 NullTool 对象:

class NullTool : public Tool
{
    Q_OBJECT

public:
    NullTool() : Tool();

public slots:
    void use()
    {
        // does nothing
    };
};

当工具被销毁时,我们的指针会很聪明,并且会知道它应该指向一个 NullTool 实例。所以 Worker::work() 可以这样实现:

void Worker::work()
{
    m_tool->use();
    emit workCompleted();
};

然后 m_tool->use() 将在什么都不做的 NullTool 上被调用,因此无需检查指针是否为空。

这是一个好主意吗?Qt提供的智能指针类是否有可能,或者我应该继承QWeakPointer?

4

3 回答 3

3

我认为空对象模式对类值类最有意义。示例是 QString 或 QVariant,如果您不想使用 if ( str && !str->isEmpty() ) 之类的代码,而只是使用 if ( !str.isEmpty() )。对于不是值但具有“身份”的 QObjects,我从未发现这很有用。

于 2010-08-31T09:29:52.273 回答
0

我不清楚您的用例,但是当对象被销毁时,可以通过连接来自 QObject 的以下信号来向您的程序发出信号:

void destroyed ( QObject * obj = 0 );
于 2010-08-31T08:15:36.287 回答
0

我看不出你的想法有什么问题。您只需将实现它所需的工作与每次检查指针的工作进行比较。让您检查指针 10.000 次,使用您的方法是个好主意。旁注:Tool::use()您的空对象模式依赖于没有任何副作用的事实。

请注意,Tool::use()当您将其多态替换为NullTool::use(). 换句话说:确保你没有违反 Liskov 替换原则。

于 2010-09-05T03:55:39.037 回答