Qt - 带有重载运算符的QDataStream<<用于对象指针(Class *)

时间:2014-05-16 05:49:28

标签: c++ qt operator-overloading qdatastream

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

如果我使用&#34; Card * c&#34;,数据写得很好,但是当我尝试阅读时,我得到了一个SEGFAULT。如果我使用&#34; Card *&amp; c&#34;,程序甚至无法识别我已经覆盖了操作符,因此它不会被调用。

我做错了什么?

修改

当我正在阅读或写作时会出现问题&#34;卡&#34;这是在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并保存每张卡片。

2 个答案:

答案 0 :(得分:4)

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

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

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

这是错误的,因为uninitializedPointer是..它的名字说明问题是什么,你指的是有限或随机的内存块。
可能你想要(这是错的,但它会起作用,我只是为了解释崩溃而不是修复):

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

或者:

Card object;
someDataStream >> &object;

不要尝试通过在运营商中进行分配来解决这个问题,否则你会在地狱里煎炸:) 简单地将垃圾运算符重载为指针,你真的不需要它们。

答案 1 :(得分:1)

流运营商的预期签名是:

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

例如,请参阅How to properly overload the << operator for an ostream?QDatastream operator>> for QList<Class*>

这也适用于QDataStream。这里遇到的困难是T是指针类型,但实质上你只需用指针类型替换T。所以你的签名应该是:

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

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