2016-05-03 8 views
11

Ich habe den Code für QScopedPointer gelesen und bin auf etwas gestoßen, das ich nicht verstehen konnte.Was ist der Zweck des Operators RestrictedBool in QScopedPointer?

Hier ist der relevante Code aus QScopedPointer auf code.qt.io:

template <typename T, typename Cleanup = QScopedPointerDeleter<T> > 
class QScopedPointer 
{ 
    typedef T *QScopedPointer:: *RestrictedBool; 
public: 
... 
#if defined(Q_QDOC) 
    inline operator bool() const 
    { 
     return isNull() ? Q_NULLPTR : &QScopedPointer::d; 
    } 
#else 
    inline operator RestrictedBool() const 
    { 
     return isNull() ? Q_NULLPTR : &QScopedPointer::d; 
    } 
#endif 
... 
inline bool isNull() const 
{ 
    return !d; 
} 
... 
protected: 
    T *d; 

Ich verstehe die Präprozessordefinition die QDOC denken QScopedPointer hat eine operator bool statt operator RestrictedBool macht. Was ich nicht verstehe, welcher Zweck RestrictedBool dient und wie es funktioniert. Zum Beispiel kann eine einfachere Implementierung ist:

inline operator bool() const 
{ 
    return !isNull(); 
} 

Kurz: Was hier passiert? Warum gibt operator RestrictedBool hinterhältig die Adresse d zurück und warum existiert sie an erster Stelle anstatt operator bool?

+5

würde ich Sagen wir, es ist der Qt-Weg von 'explicit operator bool' (vor C++ 11). – Jarod42

+2

ist auf explizite Konvertierungen beschränkt – user463035818

+2

[http://lists.qt-project.org/pipermail/development/2012-Januar/001433.html] hat mich dazu gebracht, [this] (http: //www.artima .com/cppsource/Safebool.html), die die dahinterstehende Idee zu erklären scheint – user463035818

Antwort

9

Dies ist eine Implementierung der Safe Bool Idiom, erklärt here.

Die naive Umsetzung:

inline operator bool() const 
{ 
    return !isNull(); 
} 

gibt einen rvalue von bool die implizit für andere Operationen verwendet werden kann, z.B.

QScopedPointer<Foo> foo(nullptr); 
int i = 1; 
if (foo < i) 
    ... 

ist gültiger Code.

Zusammenfassung:RestrictedBool ist ein privatentypedef eines Zeigers auf die Art der d. Wenn Sie es als Rückgabetyp für einen Operator verwenden, bedeutet dies, dass es in einer if-Anweisung (if (foo)) verwendet werden kann, aber nicht mit anderen Operatoren verwendet werden kann.

Hinweis:C++11 allows the use of explicit operator bool, die die Notwendigkeit für das sicheres Bool Idiom in C++ 11 oder später Code beseitigt. Eine Implementierung für QScopedPointer in C++ 11 könnte wie folgt aussehen:

explicit operator bool() const 
{ 
    return !isNull(); 
} 

Danke tobi303 und Jarod42 für die Grundlage für diese Antwort zu geben.

Literaturhinweise bezüglich ++ 11 C und die sichere Bool Idiom:

+1

Heh, hast du etwas wie https://codereview.qt-project.org/#/c/158069/ gesagt? :-) – peppe

+0

Gehe ich fälschlicherweise davon aus, dass das explizite bool noch 'if (foo)' erlaubt? –

+0

Okay. Ich habe die C++ 11-Referenz nicht angegeben, da ich unbedingt nachlesen muss, wie 'explicit operator bool' funktioniert. –

Verwandte Themen