QT - QDataStream与重载的operator <<为对象的指针(类*)(

2019-10-20 03:43发布

我想读/使用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);

如果我使用“卡* C”,将数据写入罚款,但我得到一个段错误,当我尝试读取。 如果我使用“卡*&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的*卡?

编辑:

按照马立克的r的答案,我找了一个方法,以避免写卡*。 解决的办法是通过QHash迭代并保存每一个人卡。

Answer 1:

第一个问题是您要为指针做这个操作。 如果我的同事会做我可能会尝试把他掐死。 病例的99.9999%的人从未超载运营商指针。

如果你坚持这样做,我猜你有这个操作符的使用的代码如下所示:

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

这是错误的,因为uninitializedPointer是..它的名字一样是什么问题,你是指的内存限制或随机块。
也许你想(这是错误的,但它会工作,我展示这只能解释崩溃不是修复):

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

要么:

Card object;
someDataStream >> &object;

不要试图解决这个问题通过做分配的运营商,否则你会在地狱:)超载,你真的不需要它们的指示简单的垃圾运营商炒。



Answer 2:

对于流运营商预期的签名是:

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

请参阅如何正确重载<<操作为一个ostream? 或QDatastream操作者>>为的QList <类*>用于实例。

这适用于QDataStream为好。 这里的困难来自一个事实,即T为指针类型,但实际上你只是更换T你的指针类型。 所以,你的签名应该是:

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

需要注意的位置constCard* const ,因为它是一个需要常量,而不是指针对象的指针。



文章来源: Qt - QDataStream with overloaded operator<< for object pointer (Class*)