C++中重载输入输出操作符

QT中封装了数据流类QDataStream和模板类QList。有时需要往流里写模板类对象,但是,QDataStream中,没有参数匹配的运算符重载函数operator<< 。此时需要重载输入输出操作符函数,使之能支持模板类。
比如,自定义一个类:
#include <QString>
class UserType
{
public:
UserType();
QString id;
QString name;
};
实例化模板类QList<UserType>,声明一个UserType类型的对象链表:
UserType u1, u2;
u1.id = "1";
u1.name = "1";
u2.id = "2";
u2.name = "2";
QList<UserType> list;
list.append(u1);
list.append(u2);
假如需要往QDataStream流中写这个模板类对象。代码如下:
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << list;
编译会报错,QDataStream & operator<< (const QList<UserType> & list )函数不存在。同样,从流中读出一个模板类对象,也会有类似的错误。因为在QT的QDataStream类中,没有定义好的参数匹配的输入输出操作符函数operator<<。
解决问题的办法是,实现两个非成员函数。代码如下:
QDataStream & operator<< ( QDataStream & out, const QList<UserType> & list )
{
int i;
for (i = 0; i < list.count(); i++)
{
out << list.at(i).id << list.at(i).name;
}
return out;
}
QDataStream & operator>> ( QDataStream & in, QList<UserType> & list )
{
while (!in.atEnd())
{
UserType t;
in >> t.id;
in >> t.name;
list.append(t);
}
return in;
}
这样往流里写模板类对象,就不会出错,当从流中读出数据时,就用到了operator>>函数。示例代码如下:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
UserType u1, u2;
u1.id = "1";
u1.name = "1";
u2.id = "2";
u2.name = "2";
QList<UserType> list;
list.append(u1);
list.append(u2);
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << list;
//……
QList<UserType> list2;
QDataStream in(&block, QIODevice::ReadOnly);
in >> list2;
int i;
for (i = 0; i < list2.count(); i++)
{
ui->listWidget->addItem(list2.at(i).id);
ui->listWidget->addItem(list2.at(i).name);
}
}

  

时间: 2024-12-21 14:13:41

C++中重载输入输出操作符的相关文章

【c++】c++中重载输出操作符,为什么要返回引用

针对:ostream & operator <<(ostream & os, const ClassType &object) 说明几点: 1.第一个形参为对ostream对象的引用,在该对象上将产生输出,ostream为非const,因为写入到流会改变流的状态:该形参是一个引用,因为不能复制ostream对象(在c++中定义的标准输入输出流类istream和ostream,其中拷贝构造函数和赋值操作符函数都被放置在了private部分,且只有声明,没有定义). 2.第

C++ 之 重载赋值操作符

下面是一个基类 Bitmap 和派生类 Widget, Widget 中定义了一个私有类型 (private) 指针 pb class Bitmap { ... }; class Widget { ... private: Bitmap *pb; // ptr to a heap-allocated object };   当在 Widget 类中重载赋值操作符 "=" 时,需要考虑以下几个方面 1  链式赋值 首先要考虑的是,链式赋值 (chain of assignments) 的

C++重载赋值操作符

1.C++中重载赋值操作函数应该返回什么? 类重载赋值操作符一般都是作为成员函数而存在的,那函数应该返回什么类型呢?参考内置类型的赋值操作,例如 int x,y,z; x=y=z=15; 赋值行为相当于x=(y=(z=15)),也就是赋值操作应该返回左操作数的引用,因此,为了和内置类型兼容,类中重载赋值操作符应该返回左操作数的引用,即*this,如下类A的重载赋值操作函数的声明, class A{}; A& A::operator=(const A&); 2.确保重载赋值操作具有良好的行为

C#中如何利用操作符重载和转换操作符

原文:C#中如何利用操作符重载和转换操作符 操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成把两个整数加到一起的代码. 当编译器发现两个string类型的实例使用+操作符的时候,编译器会生成把两个字符串连接到一起的代码.那么编译器怎么就会知道这样做呢?如何进行操作符重载呢? 下面C#代码展示了一个类中如何进行操作符重载: namespace Do

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符、成员函数方式重载、友元函数方式重载

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符.成员函数方式重载.友元函数方式重载 引言: 明智地使用操作符重载可以使类类型的使用像内置类型一样直观! 一.重载的操作符名 像任何其他函数一样,操作符重载函数有一个返回值和一个形参表.形参表必须具有操作符数目相同的形参.比如赋值时二元运算,所以该操作符函数有两个参数:第一个形参对应着左操作数,第二个形参对应右操作数. 大多数操作符可以定义为成员函数或非成员函数.当操作符为成员函数时,它的第一个操作数隐式绑定

C++重载IO操作符

操作符的重载有一定的规则,而IO操作符必须重载为普通函数,且应该声明为类的友元函数.我试了,非友元也可以,但是必须提供访问成员变量的函数,所以,出于效率的考虑还是应该定义为友元. 规则如下: 1.  重载操作符必须具有一个类类型或枚举类型操作数.这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含义. 如: int operator+(int, int), 不可以 2.  为类设计重载操作符的时候,必须选择是将操作符设置为类成员还是普通非成员函数.在某些情况下,程序没有选择,操作符必须

C++ 拷贝构造函数和重载赋值操作符相互调用分析 [转]

结论: 从面相对象编程的角度考虑,拷贝构造函数调用重载赋值操作符,重载赋值操作符调用拷贝构造函数的写法都是没有意义的.应该避免. Don't try to implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both call. ——Effective C++ Third Edition By Scott M

js中的new操作符

一.js中new操作符来声明一个对象:例如有如下一个实例function Person(){Person.prototype.fn=function(){console.log(1);}}var p=new Person(); 上例中使用new操作符来声明一个对象实际上是进行了三个动作: 1.var p={}; 2.p._proto_=Person.prototype; 3.Person.call(p); 二.以上的三个操作是在使用new操作符创建对象的时候实际执行的动作. 以上为本人对new操

为什么不要在 JavaScript 中使用位操作符?

如果你的第一门编程语言不是 JavaScript,而是 C++ 或 Java,那么一开始你大概会看不惯 JavaScript 的数字类型.在 JavaScript 中的数字类型是不区分什么 Int,Float,Double,Decimal 的.咳咳,我说的当然是在 ES6 之前的 JS,在 ES6 的新标准中提出了像 Int8Array 这样新的数据类型.不过这不是本文叙述的重点,暂且就不谈啦.本文将更着重地谈 JS 的数字类型以及作用于它的位操作符,而关于包装对象 Number 的更多了解可以