2010-04-20 23 views
17

Estoy intentando crear más mensajes de depuración útiles para mi clase donde almacenar datos. Mi código está buscando algo como estoCómo sobrecargar el operador << para 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; 
} 

espero qDebug() << model imprimirá "Hello World!". Sin embargo, siempre hay algo así como "QAbstractTableModel (0x1c7e520)" en la salida.

¿Tiene alguna idea de lo que está mal?

+3

1. Parece que Qt quiere que el operador de flujo sea: QDebug operator << (QDebug dbg, const DataModel & model) [es decir, devolver y pasar QDebug por valor], ver http://doc.trolltech.com/4.6 /debug.html#providing-support-for-the-qdebug-stream-operator 2. lo ha declarado como: amigo QDebug & operator << (const QDebug & d, modelo DataModel); pero lo definió sin la const: QDebug & operator << (QDebug & d, modelo DataModel) [aunque probablemente sea solo un error de copiar/pegar - tu código no debería vincular] –

Respuesta

11

Después de jugar durante una hora con esta pregunta, calculé que model es un puntero a DataModel y mi operador << toma solo referencias.

+16

¡Solo una hora, tienes suerte! –

+2

Disculpe, ¿puede extender su respuesta un poco más? Estoy tratando de lograr lo mismo, pero no puedo. Gracias de antemano –

7

En su ejemplo, qDebug() imprime la dirección de su variable, que es el comportamiento predeterminado para los tipos desconocidos.

De hecho, parece que hay dos cosas que tienes que tener cuidado de: (! Eugen ya lo señaló)

  • conseguir el artículo por valor.
  • Defina el operador de sobrecarga antes de usarlo, ponga su firma en el archivo de encabezado o defínalo como reenviar antes de usarlo (de lo contrario obtendrá el comportamiento predeterminado "qDebug() < <").

Esto le dará:

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

o

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

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

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

que he aprendido de la manera difícil, también ...

16

sé que hace mucho tiempo, pero solo para ser documentado y para ayudar a cualquier otra persona que eventualmente venga aquí teniendo la misma duda, la forma más fácil de obtener qDebug() < < trabajando con su propia clase imprimiendo algo así como "Hello World" o cualquier otra cosa, es implementar la conversión implícita de su clase a un tipo imprimible, como QString (que es bien soportado por QDebug).

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

}; 
+3

Esto es mucho más útil y manejable que la sobrecarga '<<'. ¡Gracias! –

+1

Al pensar en esta pregunta, la primera solución en este tema (operador de sobrecarga <<) será la única solución SI la clase que desea imprimir es de un tercero. Si la implementación de la clase es suya, mi enfoque es mucho más simple que el otro. –

+2

¡Santa vaca! Aprendí algo nuevo. ¡Gracias! –

2

He encontrado this answer en el Foro de QT por azabache Worx (dar crédito a quien crédito merece!)

En el archivo .h:

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

donde MyType es su clase , como DataModel y type es la instancia que se mostrará.

Y en el archivo .cpp:

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

y se puede utilizar space(), nospace(), y otros métodos de la QDebug para controlar la visualización exacta de la corriente.

Así que para el PO, usaríamos:

// 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

ha implementado sólo el operador < < para una referencia. Si su variable model es un puntero, usará otra implementación (no la suya).

Para utilizar la aplicación que puede hacer:

qDebug() << *model 

Por cierto, la forma correcta para implementar una sobrecarga QDebug operator<<(QDebug dbg, const T &data) es utilizar la clase QDebugStateSaver:

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

De esta manera los ajustes (es decir, si insertar o no espacios entre las impresiones) se restaurará correctamente al salir de la función.

Cuestiones relacionadas