Qt - 带有重载运算符的 QDataStream<<用于对象指针 (Class*)
Qt - QDataStream with overloaded operator<< for object pointer (Class*)
我正在尝试使用QDataStream读/写我的自定义类。我已经重写了<<还有>>运算符,它们似乎可以很好地处理普通对象。但是,当我尝试将指针传递给自定义对象时,覆盖的操作符不能正常工作。
下面是来自card.h的相关数据:
#ifndef CARD_H
#define CARD_H
#include <QDataStream>
#include <QImage>
#include <QString>
class Card
{
private:
QString name;
QImage image;
QString type;
int strength;
int movement;
int deployCost;
QString back;
public:
Card();
QDataStream& read(QDataStream &dataStream);
QDataStream& write(QDataStream &dataStream) const;
...
};
QDataStream& operator <<(QDataStream &out, const Card &c);
QDataStream& operator >>(QDataStream &in, Card &c);
QDataStream& operator <<(QDataStream &out, const Card *c);
QDataStream& operator >>(QDataStream &in, Card *c);
//QDataStream& operator <<(QDataStream &out, const Card *&c);
//QDataStream& operator >>(QDataStream &in, Card *&c);
#endif // CARD_H
这里是card.cpp:
#include "card.h"
Card::Card()
{
}
QDataStream& operator <<(QDataStream &out, const Card &c) {
return c.write(out);
}
QDataStream& operator >>(QDataStream &in, Card &c) {
return c.read(in);
}
QDataStream& operator <<(QDataStream &out, const Card *c) {
return c->write(out);
}
QDataStream& operator >>(QDataStream &in, Card *c) {
return c->read(in);
}
/*QDataStream& operator <<(QDataStream &out, const Card *&c) {
return c->write(out);
}
QDataStream& operator >>(QDataStream &in, Card *&c) {
return c->read(in);
}*/
QDataStream& Card::read(QDataStream &dataStream) {
dataStream >> name;
dataStream >> image;
dataStream >> type;
dataStream >> strength;
dataStream >> movement;
dataStream >> deployCost;
dataStream >> back;
return dataStream;
}
QDataStream& Card::write(QDataStream &dataStream) const {
dataStream << name;
dataStream << image;
dataStream << type;
dataStream << strength;
dataStream << movement;
dataStream << deployCost;
dataStream << back;
return dataStream;
}
...
如你所见,我都试过了
QDataStream& operator <<(QDataStream &out, const Card *c);
QDataStream& operator >>(QDataStream &in, Card *c);
和
//QDataStream& operator <<(QDataStream &out, const Card *&c);
//QDataStream& operator >>(QDataStream &in, Card *&c);
如果我使用"Card *c",数据写得很好,但是当我试图读取时,我得到一个SEGFAULT。如果我使用"Card *&c",程序甚至不知道我已经覆盖了操作符,所以它不会被调用。
我做错了什么?
编辑:当我读取或写入"卡片"时,问题出现了,这是在deck.h中定义的QHash
QHash<QString, Card*> cards;
deck.h:
#ifndef DECK_H
#define DECK_H
#include <QDataStream>
#include <QHash>
#include "card.h"
class Deck
{
private:
QString name;
QHash<QString, Card*> cards;
public:
Deck();
QDataStream &read(QDataStream &dataStream);
QDataStream &write(QDataStream &dataStream) const;
...
};
QDataStream &operator<<(QDataStream &out, const Deck &d);
QDataStream &operator>>(QDataStream &in, Deck &d);
#endif // DECK_H
deck.cpp:
#include "deck.h"
Deck::Deck()
{
}
QDataStream &operator<<(QDataStream &out, const Deck &d) {
return d.write(out);
}
QDataStream &operator>>(QDataStream &in, Deck &d) {
return d.read(in);
}
QDataStream &Deck::read(QDataStream &dataStream) {
dataStream >> name;
// Reading the QHash - one problem spot
dataStream >> cards;
return dataStream;
}
QDataStream &Deck::write(QDataStream &dataStream) const {
dataStream << name;
// Writing the QHash - the other problem spot
dataStream << cards;
return dataStream;
}
...
因为卡片是作为指针存储在QHash中的,所以我不确定应该如何避免重写指针操作符。是否有更好的方法来读/写QHash,或*卡存储在QHash?
编辑:根据Marek R的回答,我寻找一种避免写卡片的方法*。解决方案是遍历QHash并保存每个单独的卡。
第一个问题是您正在尝试为指针执行此操作符。如果我的同事这么做,我可能会掐死他。在99.9999%的情况下,永远不要重载指针的操作符。
如果你坚持这样做,我猜你的代码使用这个操作符看起来像这样:
Card *uninitializedPointer;
someDataStream >> uninitializedPointer; // SEGFAULT
这是错误的,因为uninitializedPointer
是…它的名字说明了问题所在,您指的是受限或随机内存块。
也许你想要(这是错误的,但它会工作,我显示这个只是为了解释崩溃,而不是作为一个修复):
Card *initializedPointer = new Card;
someDataStream >> initializedPointer;
或:
Card object;
someDataStream >> &object;
不要试图通过在操作符中做分配来修复这个问题,否则你会在地狱里被炒菜:)只需将指针重载的操作符丢弃
流操作符的期望签名如下:
stream& operator<<(stream& out, const T& t);
stream& operator>>(stream& in, T& t);
参见如何正确重载<<ostream的操作符?或QDatastream operator>>QList<类*比;例如,>
这也适用于QDataStream。这里的困难在于T
是一个指针类型,但本质上你只是用指针类型代替T
。所以你的签名应该是:
QDataStream& operator<<(QDataStream &out, Card* const& c);
QDataStream& operator>>(QDataStream &in, Card*& c);
注意Card* const
中const
的位置,因为它是需要const的指针,而不是指针。
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- (C 14)操作员&lt;&lt;超负荷无法正如智能指针向量所预期的那样工作