1

我正在尝试使用 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;

甲板.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

甲板.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 中的 *Card?

编辑:

根据 Marek R 的回答,我寻找了一种避免写卡片的方法*。解决方案是遍历 QHash 并保存每张卡片。

4

2 回答 2

4

第一个问题是您正在尝试为指针执行此运算符。如果我的同事这样做,我可能会试图勒死他。对于 99.9999% 的情况,从不为指针重载运算符。

如果您坚持这样做,我猜您使用此运算符的代码如下所示:

Card *uninitializedPointer;
someDataStream >> uninitializedPointer; // SEGFAULT

这是错误的,因为uninitializedPointeris .. 它的名称说明了问题所在,您指的是受限或随机的内存块。
可能你想要(这是错误的,但它会起作用,我展示这个只是为了解释崩溃而不是修复):

Card *initializedPointer = new Card;
someDataStream >> initializedPointer;

或者:

Card object;
someDataStream >> &object;

不要尝试通过在运算符中进行分配来解决此问题,否则您将陷入地狱:) 只需将运算符重载为您真的不需要它们的指针即可。

于 2014-05-16T14:23:40.387 回答
3

流操作符的预期签名是:

stream& operator<<(stream& out, const T& t);
stream& operator>>(stream& in, T& t);

请参阅如何为 ostream 正确重载 << 运算符?QDatastream 运算符>> 用于 QList<Class*>例如。

这也适用于 QDataStream。这里的困难在于它T是一个指针类型,但本质上你只是用T你的指针类型替换。所以你的签名应该是:

QDataStream& operator<<(QDataStream &out, Card* const& c);
QDataStream& operator>>(QDataStream &in, Card*& c);

注意constin的位置Card* const,因为它是指针需要是 const,而不是指针。

于 2016-04-19T17:36:57.703 回答