【问题标题】:How to overload operator<< for qDebug如何为 qDebug 重载 operator<<
【发布时间】:2011-02-10 06:40:51
【问题描述】:

我正在尝试为存储数据的类创建更有用的调试消息。我的代码看起来像这样

#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;
}

我希望qDebug() &lt;&lt; model 会打印“Hello world!”。但是,输出中总会出现类似“QAbstractTableModel(0x1c7e520)”的内容。

你知道哪里出了问题吗?

【问题讨论】:

  • 1.看起来 Qt 希望流操作符是:QDebug operatordoc.trolltech.com/4.6/… 2. 你已经声明它像:friend QDebug & operator

标签: c++ qt4 operator-overloading


【解决方案1】:

我早就知道了,但只是为了记录下来并帮助任何最终来到这里有同样疑问的人,最简单的方法是让 qDebug()

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

};

【讨论】:

  • 这比重载&lt;&lt; 更有用和更易于管理。谢谢!
  • 考虑这个问题,如果您要打印的类是第三方类,则本主题中的第一个解决方案(重载运算符
  • 这非常有用,正是我想要的。我很惊讶它不在官方文档中。
  • 有人可以分享一个简单的例子来说明如何使用它吗?这对我来说是一个错误。 ```错误:二进制表达式的无效操作数('QDebug'和'const LinkConfiguration')qCCritical(PING_PROTOCOL_SENSOR)errorString();; ```
  • 隐式转换运算符到QString 可能很危险。例如,它启用了类似的功能:QVariant( myFooInstance ),但不是存储 Foo 实例,而是将其转换为 QString 并存储它。
【解决方案2】:

在您的示例中,qDebug() 打印变量的地址,这是未知类型的默认行为。

实际上,您似乎需要注意两件事:

  • 按值获取项目(并且 eugen 已经指出!)。
  • 在使用前定义重载运算符,将其签名放在头文件中,或在使用前将其定义为转发(否则您将获得默认的“qDebug()

这会给你:

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

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

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

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

我也学得很辛苦……

【讨论】:

    【解决方案3】:

    玩了一个小时后,我发现model 是指向DataModel 的指针,而我的运算符&lt;&lt; 只接受引用。

    【讨论】:

    • 抱歉,您能否进一步扩展您的答案?我试图达到同样的效果,但我做不到。提前致谢
    • 这意味着当您的签名是QDebug operator&lt;&lt; (QDebug d, const DataModel &amp;model) 时,传递DataModelDataModel* 是不一样的。初始结果QAbstractTableModel(0x1c7e520) 是一个指针并使用适当的运算符,而不是示例中定义的运算符。
    • 如果运算符只接受引用并且您的DataModel 实例存储在指针中,则在调用函数时,您只需取消引用指针即可传递引用。调用 qDebug 时,您可以这样做:qDebug() &lt;&lt; *model;
    【解决方案4】:

    您仅实现了 model 变量是一个指针,它将使用另一个实现(不是您的)。

    要使用您的实现,您可以这样做:

    qDebug() << *model
    

    顺便说一句,实现QDebug operator&lt;&lt;(QDebug dbg, const T &amp;data)重载的正确方法是使用QDebugStateSaver类:

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

    这样退出功能时设置(即打印之间是否插入空格)将正确恢复。

    【讨论】:

      【解决方案5】:

      我在 raven-worx 的 QT 论坛上找到了this answer(在应得的地方给予赞扬!)

      .h 文件中:

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

      其中MyType 是您的类,例如DataModeltype 是您将显示的实例。

      .cpp 文件中:

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

      并且可以使用QDebug的space()nospace()等方法来控制流的精确显示。

      所以对于 OP,我们将使用:

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

      【讨论】:

      • 有点奇怪的跟进......但是你怎么能用这种方法访问课堂的私人部分呢?说stram&lt;&lt;data.someMember? someMember 是私有的,我没有可以返回 const qdebug 重载的 QString getMember()const{} 函数......有什么想法吗?
      猜你喜欢
      • 2013-11-24
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2012-05-03
      • 2020-08-27
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多