前言
因为看到Qt中重载流操作符和C++中重载流操作符好像不一样,所以想研究一下。
正文
在C++中
//左移运算符的重载是<<
//为了实现直接打印对象
class Person
{
public:
int m_a;
int m_b;
};
//一般不会利用成员函数重载左移运算符,因为若是成员函数,则调用这个运算符就变成了p.operator<<(cout,p);这样就自己调用自己的成员函数并且把自己当做变量传递给函数
//而且调用的时候p.operator<<(cout)会被解释为p<<cout(因为是p调用的函数),为了使得cout在左侧
//故只能用全局函数重载<<
ostream& operator<<(ostream& cout, Person& p)//返回值是ostream&类型是为了实现cout后可以无限追加<<
{
cout << "m_a = " << p.m_a << " m_b = " << p.m_b;
return cout;
}
void test0()
{
Person p1;
p1.m_a = 13;
p1.m_b = 23;
cout << p1 << endl;
}
不懂为什么的可以去看b站黑马视频
在Qt中
实现打印自定义类
#ifndef ARCHIEVEPRINT_H
#define ARCHIEVEPRINT_H
#include <QObject>
#include <QDebug>
class ArchievePrint : public QObject
{
Q_OBJECT
public:
explicit ArchievePrint(QObject *parent = nullptr);
// 声明为友元函数
friend QDebug operator<<(QDebug dbg, const ArchievePrint& obj);
signals:
private:
int m_data;
QString m_str;
qreal m_fdata;
};
#endif // ARCHIEVEPRINT_H
//cpp
#include "archieveprint.h"
ArchievePrint::ArchievePrint(QObject *parent)
: QObject(parent)
,m_data(10)
,m_str("hello qDebug")
,m_fdata(3.0)
{
}
// 重载 QDebug 的 << 运算符
QDebug operator<<(QDebug dbg, const ArchievePrint& obj) {
// 保存当前的 QDebug 状态
QDebugStateSaver saver(dbg);
dbg.nospace() << " m_data:" << obj.m_data << " m_str:" <<obj.m_str <<" m_fdata:" <<obj.m_fdata;
return dbg.space();
}
// main.cpp
#include <QCoreApplication>
#include "archieveprint.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ArchievePrint apt;
qDebug()<< apt;
return a.exec();
}
运行结果
实现自定义类的序列化和反序列化
#ifndef ARCHIEVESERIALIZATION_H
#define ARCHIEVESERIALIZATION_H
#include <QObject>
#include <QTextStream>
#include <QDataStream>
class ArchieveSerialization : public QObject
{
Q_OBJECT
public:
explicit ArchieveSerialization(QObject *parent = nullptr);
ArchieveSerialization(qreal data,QObject *parent = nullptr);
// 重载QTextStream的<<,用于序列化
friend QTextStream& operator<<(QTextStream& out, const ArchieveSerialization& obj);
// 重载QTextStream的>>,用于反序列化
friend QTextStream& operator>>(QTextStream& in, ArchieveSerialization& obj);
// 这两个就不写了,和上面两个一样
// // 重载QDataStream的<<,用于序列化
// friend QDataStream& operator<<(QDataStream& out, const ArchieveSerialization& obj);
// // 重载QDataStream的>>,用于反序列化
// friend QDataStream& operator>>(QDataStream& in, ArchieveSerialization& obj);
signals:
private:
qreal value;
};
#endif // ARCHIEVESERIALIZATION_H
//cpp
#include "archieveserialization.h"
ArchieveSerialization::ArchieveSerialization(QObject *parent) : QObject(parent)
{
}
ArchieveSerialization::ArchieveSerialization(qreal data,QObject *parent)
{
value = data;
}
QTextStream &operator>>(QTextStream &in, ArchieveSerialization &obj)
{
in >> obj.value;
return in;
}
QTextStream &operator<<(QTextStream &out, const ArchieveSerialization &obj)
{
out << obj.value;
return out;
}
// main.cpp
#include <QCoreApplication>
#include "archieveserialization.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ArchieveSerialization obj1(3.0), obj2(5.0), obj3(3.7);
QTextStream out(stdout);
out << "output data:"<<obj1<<" "<<obj2<<" "<<obj3<<endl;
return a.exec();
}
运行结果
话题之外
"<<"
和">>"
对于整形数据而言如 int
, unsigned int
, long
, short
等就是左移、右移运算符号,左移一位相当于乘以2,移动3位相当于乘以8,右移一位相当于除以2,移动三位相当于除以8,如
int a = 3, b = 23, c = 11, d = 234;
a = a<<1;
b = b>>1;
c = c<<3;
d = d>>3;
qDebug()<<"a:"<<a<<" b:"<<b<<" c:"<<c<<" d:"<<d;
//运行结果a: 6 b: 11 c: 88 d: 29
小结
我现在才明白我们根据我们所需要的功能进行重载,比如我想调用qDebug
直接打印我自定义类的对象,那么我这个类就要重载QDebug
的<<
操作符;当我想通过流操作符序列化和反序列化自定义类的内容时,就可以重载QTextStream
或者QDataStream
的流操作符。