1
votes

I am working with Qt 5.10 and I have to subclass QDatastream and I overload the operator << with an other class, like this :

class myDataStream:public QDataStream
{
public :
    myDataStream(QIODevice* device):QDataStream(device)
    {}
};

class data
{
public:
    data(double v):data_(v) {}
    double getData()  const {return data_;}

    void record(myDataStream& stream) const;

private:
    double data_;
};

void data::record(myDataStream &stream) const
{
    stream<<getData();
}

myDataStream &operator<<(myDataStream &stream, const data &d )
{
    stream<<d.getData(); //<------ Error here
    return stream;
}

I have this error :

> error: use of overloaded operator '<<' is ambiguous (with operand types 'myDataStream' and 'double')

When I remove the const operator behind data like this :

myDataStream &operator<<(myDataStream &stream, data &d )
    {
        stream<<d.getData();
        return stream;
    }

I don't have error. The operator<< doesn't change the class data ... doesn' it ? the getData() method is const.

I don't understand.

Someone to help me ?

1
@eyllanesc, i don't think it is the same problem. I don't think the operator<< change the class data. The getData() method is const. - vcloarec
QDataStream is essentially a final class. Why are you aubclassing it? It wasn’t really designed to be subclassed. If you want a custom stream that hands off some implementation to QDataStream, you should use composition or private inheritance — your class is not a QDataStream anymore. Your stream operators can then be forwarding to QDS implementations as needed. The compiler is giving you a subtle hint about it. Of course there is a “fix” to the compiler error, but it only camouflages the fundamental design bug you have. - Kuba hasn't forgotten Monica
@Kuba Ober, but how to explain the error ? - vcloarec
@vcloarec There are no hooks provided to specialize the base class. Your class violates the Liskov Substitution Principle and will utterly fail whenever its users end up accessing it through the base class type. This has nothing to do with Qt, of course. You’re making a class that behaves correctly only when accessed by the derived type — that’s not “specialization”, that’s pure breakage. There’s nothing stopping you from private inheritance. You can generically forward operator<< to use the QDataStream implementation when appropriate. So the public inheritance buys you nothing here. - Kuba hasn't forgotten Monica

1 Answers

1
votes

Finaly, I will follow the KubaOber advices (in comments of my questions) and make QDataStream a composition of my class instead of subclassing QDataStream.

Thanks to KubaOber for its advices !