2010-04-20 36 views
17

überladen Ich versuche, nützlichere Debug-Nachrichten für meine Klasse zu erstellen, wo Daten speichern. Mein Code sieht so etwas wie diesesWie Operator << für qDebug

#include <QAbstractTableModel> 
#include <QDebug> 

/** 
    * Model for storing data. 
    */ 
class DataModel : public QAbstractTableModel { 
    // for debugging purposes 
    friend QDebug operator<< (QDebug d, const DataModel &model); 

    //other stuff 
}; 

/** 
    * Overloading operator for debugging purposes 
    */ 
QDebug operator<< (QDebug d, const DataModel &model) { 
    d << "Hello world!"; 
    return d; 
} 

I qDebug() << model erwarten druckt "Hallo Welt!". Es gibt jedoch immer etwas wie "QAbstractTableModel (0x1c7e520)" auf der Ausgabe.

Haben Sie eine Idee, was los ist?

+3

1. Es sieht so aus, als ob Qt den Stream-Operator haben möchte: QDebug operator << (QDebug dbg, const DataModel & model) [nämlich Rückgabe und Weitergabe von QDebug nach Wert], siehe http://doc.trolltech.com/4.6 /debug.html#providing-support-for-the-qdebug-stream-operator 2. Sie haben es wie folgt erklärt: Freund QDebug & Operator << (Const QDebug & d, DataModel-Modell); aber definiere es ohne const: QDebug & operator << (QDebug & d, DataModel-Modell) [obwohl es wahrscheinlich nur ein Copy/Paste-Fehler ist - dein Code sollte es nicht verlinken] –

Antwort

11

Nach einer Stunde mit dieser Frage zu spielen habe ich herausgefunden model ist Zeiger auf DataModel und mein Operator << nimmt nur Referenzen.

+16

Nur eine Stunde - du hast Glück! –

+2

Entschuldigung, können Sie bitte Ihre Antwort ein wenig erweitern? Ich versuche das gleiche zu erreichen, aber ich kann nicht. Vielen Dank im Voraus –

7

In Ihrem Beispiel gibt qDebug() die Adresse Ihrer Variablen aus, die das Standardverhalten für unbekannte Typen ist.

In der Tat scheint es zwei Dinge, die Sie ergreifen müssen, um die Betreuung von: (! Und eugen schon wies sie darauf hin)

  • Holen Sie sich den Artikel von Wert.
  • Definieren Sie den Überladungsoperator, bevor Sie ihn verwenden, legen Sie seine Signatur in die Headerdatei oder definieren Sie ihn als Weiterleiten, bevor Sie ihn verwenden (andernfalls erhalten Sie das Standardverhalten "qDebug() < <").

Dies wird Ihnen geben:

QDebug operator<< (QDebug d, const DataModel &model) { 
    d << "Hello world!"; 
    return d; 
} 
DataModel m; 
qDebug() << "m" << m; 

oder

QDebug operator<< (QDebug d, const DataModel &model); 

DataModel m; 
qDebug() << "m" << m; 

QDebug operator<< (QDebug d, const DataModel &model) { 
    d << "Hello world!"; 
    return d; 
} 

Ich habe es auf die harte Tour gelernt, auch ...

16

Ich weiß es jetzt lange Zeit, aber nur um dokumentiert zu werden und anderen Menschen zu helfen, die schließlich hierher kommen und die gleichen Zweifel haben, ist der einfachste Weg, um qDebug() < < zu arbeiten Mit Ihrer eigenen Klasse, die etwas wie "Hello World" oder was auch immer, druckt, implementieren Sie eine implizite Konvertierung Ihrer Klasse in einen druckbaren Typ wie QString (was von QDebug gut unterstützt wird).

class Foo { 
public: 
    Foo() { } 
    operator QString() const { return <put your QString here>; } 

}; 
+3

Dies ist viel nützlicher und überschaubarer als das Überladen von << <<. Vielen Dank! –

+1

Wenn Sie über diese Frage nachdenken, ist die erste Lösung in diesem Thema (Überladen des Operators) die einzige Lösung, wenn es sich bei der Klasse, die Sie drucken möchten, um eine Drittanbieterlösung handelt. Wenn die Klassenimplementierung Ihnen gehört, ist mein Ansatz viel einfacher als der andere. –

+2

Heilige Kuh! Ich habe etwas Neues gelernt. Vielen Dank! –

2

fand ich this answer auf das QT-Forum von Raben-worx (geben Kredit, wem Ehre gebührt!)

In der .h Datei:

QDebug operator<<(QDebug dbg, const MyType &type); 

wo MyType ist Ihre Klasse , wie DataModel und type ist die Instanz, die Sie anzeigen werden.

Und in der .cpp Datei:

QDebug operator<<(QDebug dbg, const MyType &type) 
{ 
    dbg.nospace() << "MyType(" << .... << ")"; 
    return dbg.maybeSpace(); 
} 

und Sie können den space() des qDebug verwenden, nospace() und andere Methoden, um die genaue Anzeige des Stroms zu steuern.

Also für den OP, würden wir verwenden:

// in the .h file: 
class DataModel : public QAbstractTableModel { 
// stuff 
}; 
QDebug operator<<(QDebug dbg, const DataModel &data); 

// in the .cpp file: 
QDebug operator<<(QDebug dbg, const DataModel &data) 
{ 
    dbg.nospace() << "My data {" << data.someField << ',' << data.another << "}"; 
    return dbg.maybeSpace(); 
} 

// in some .cpp user of the class: 
DataModel myData; 

. . . 

QDebug() << "The current value of myData is" << myData; 
0

Sie implementiert nur die < < Operator für eine Referenz. Wenn Ihre Variable model ein Zeiger ist, wird sie eine andere Implementierung (nicht Ihre) verwenden.

Ihre Implementierung verwenden Sie tun können:

qDebug() << *model 

By the way, der richtige Weg, um eine QDebug operator<<(QDebug dbg, const T &data) Überlastung zu implementieren, ist die QDebugStateSaver Klasse zu verwenden:

QDebug operator<<(QDebug dbg, const QDataflowModelOutlet &outlet) 
{ 
    QDebugStateSaver stateSaver(dbg); 
    dbg.nospace() << ...; 
    return debug; 
} 

Auf diese Weise werden die Einstellungen (dh ob Leerzeichen zwischen den Ausdrucken eingefügt werden sollen oder nicht) wird beim Verlassen der Funktion korrekt wiederhergestellt.