【问题标题】:Qt - QDataStream with overloaded operator<< for object pointer (Class*)Qt - 带有重载运算符的 QDataStream<< 用于对象指针(类 *)
【发布时间】:2014-07-04 19:07:55
【问题描述】:

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

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

编辑:

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

【问题讨论】:

  • 如果你尝试了Card *&amp;c,为什么他们仍然被评论?如果您对那部分代码有疑问,请不要在您的帖子中发表评论。
  • 我把它放在那里是为了证明我已经尝试了两种方式。但是,程序不会同时编译,因为它会产生歧义,所以我注释掉了一个。

标签: c++ qt operator-overloading qdatastream


【解决方案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的是指针,而不是pointee。

【讨论】:

    【解决方案2】:

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

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

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

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

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

    或者:

    Card object;
    someDataStream >> &object;
    

    不要尝试通过在操作符中进行分配来解决这个问题,否则你会在地狱中煎熬 :) 只需将运算符重载为您真正不需要的指针即可。

    【讨论】:

    • 我很想摆脱指针的运算符。我添加了有关QHash&lt;QString, Card *&gt; 的操作员调用的信息。我该如何解决这个问题?
    • 我刚刚意识到我可以通过遍历 QHash 并保存每张卡片来避免卡片*。感谢您的帮助!
    猜你喜欢
    • 2018-10-12
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多