2010-08-31 5 views
3

(C++/Qt) J'ai un pointeur intelligent vers un objet QObject. Disons un QWeakPointer. Pour une raison externe (quelque chose qui pourrait arriver dans un autre objet ou à cause d'un événement), il est possible que l'objet pointé soit détruit. Comme j'ai un pointeur intelligent, il n'y aura pas de référence, donc il n'y a pas de problème. Mais je dois toujours vérifier si le pointeur est nul ou non.Motif nul avec QObject

Je pense à utiliser le modèle nul afin d'éviter de le vérifier tout le temps mais je ne suis pas sûr que cela soit possible ou pratique avec un QObject. L'idée serait que le pointeur pointe vers l'objet et au cas où il serait détruit, le pointeur intelligent change son objet pointé en un objet nul. Est-ce une bonne idée ou devrais-je l'oublier et juste vérifier si le pointeur est NULL tout le temps?


Voyons un exemple. Nous avons un travailleur qui utilise un outil pour faire son travail:

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

Dans ce cas, l'outil est un objet de domaine public d'une bibliothèque, qui est utilisée par le travailleur. Je développe une telle bibliothèque. Donc, le travailleur utilise un tournevis, mais il se casse et est détruit. Aucun problème:

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

m_tool vaut 0, donc il ne fait simplement rien. Mais nous devons vérifier que ce n'est pas nul à chaque fois.

Maintenant, nous allons dire que nous avions un objet NullTool:

class NullTool : public Tool 
{ 
    Q_OBJECT 

public: 
    NullTool() : Tool(); 

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

Lorsque l'outil a été détruit, notre pointeur serait intelligent et je sais qu'il doit pointer vers une instance NullTool. Donc, travailleur :: travail() pourrait être mis en œuvre comme ceci:

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

m_tool-> utiliser() serait alors obtenir appelé le NullTool qui ne fait rien, il n'y aurait pas besoin de vérifier le pointeur est non nul .

Est-ce une bonne idée? Est-ce possible avec les classes de pointeurs intelligentes que Qt fournit ou devrais-je sous-classer QWeakPointer?

+0

Je ne vois aucun problème à vérifier si 'm_tool' est null. Quelle est votre préoccupation ? – tibur

Répondre

0

Je ne comprends pas bien votre cas d'utilisation, mais votre programme peut être signalé lorsque l'objet a été détruit en connectant le signal suivant de QObject:

void destroyed (QObject * obj = 0); 
3

Je pense que le modèle d'objet nul est plus logique pour les classes de valeur. Les exemples sont QString ou QVariant, si vous ne voulez pas avoir le code comme si (str & &! Str-> isEmpty()) mais juste si (! Str.isEmpty()). Pour QObjects, qui ne sont pas des valeurs mais qui ont une "identité", je n'ai jamais trouvé cela utile.

0

Je ne vois aucun problème dans votre idée. Vous avez juste à comparer le travail qu'il faut pour l'implémenter par rapport au travail pour vérifier le pointeur à chaque fois. Vérifions le pointeur 10.000 fois c'est une bonne idée d'utiliser votre approche. Note latérale: Votre modèle d'objet nul repose sur le fait que Tool::use() n'a aucun effet secondaire que ce soit.

Veiller à ce que les effets secondaires possibles dans Tool::use() ne vous gênent pas lorsque vous le remplacez polymorphiquement par NullTool::use(). En d'autres termes: Assurez-vous de ne pas enfreindre le principe de substitution de Liskov.