Przeciążenie operatora << (multiple definition)

0

Hej!

Tworzę klasę "SegMem" która musi współpracować ze strumieniami danych.

#include <QDataStream>
#include <QFile>

#include "segmem.h"

SegMem & operator <<(QDataStream &stream, SegMem &segmem){
    Q_UNUSED(stream);
    return segmem;
}

int main(){
    QFile file("out.bin");
    file.open(QFile::WriteOnly);

    QDataStream stream(&file);
    SegMem segmem;

    stream << segmem;

    file.close();
    return 0;
}

W powyższym przykładzie, nie ma znaczenia jak napisana jest klasa SegMem.
Problem pojawia się gdy chcę przerzucić

SegMem & operator <<(QDataStream &stream, SegMem &segmem){
    Q_UNUSED(stream);
    return segmem;
}

do pliku nagłówkowego segmem.h

segmem.o: In function `operator<<(QDataStream&, SegMem&)':
segmem.h:12: multiple definition of `operator<<(QDataStream&, SegMem&)'
segmem.h:12: first defined here

Czemu występuje wielokrotna definicja?
Rozumiem że jak kilka razy się zainkluduje to ten problem może być (tutaj może jaki moc dodatkowo inkluduje).

Czemu nie ma problemu w analogicznie napisanym qdatastream.h:

/* ... */
template <typename T>
QDataStream& operator<<(QDataStream& s, const QList<T>& l)
{
    s << quint32(l.size());
    for (int i = 0; i < l.size(); ++i)
        s << l.at(i);
    return s;
}
/* ... */

Może być wielokrotnie inkludowany z różnych miejsc i działa
:(

0

Łamiesz One Definition Rule. Albo zdefiniuj funkcję z atrybutem inline, albo przerzuć jej definicję do jednego pliku .cpp.

0

Rozumiem, ale dlaczego taki błąd nie występuje w przypadku:

// fragment pliku qdatastream.h
template <typename T>
QDataStream& operator<<(QDataStream& s, const QList<T>& l)
{
    s << quint32(l.size());
    for (int i = 0; i < l.size(); ++i)
        s << l.at(i);
    return s;
}

?

0

Ponieważ szablony (i definicje funkcji wewnątrz klas) mogą być zdefiniowane w wielu TU bez łamania ODR o ile ich definicje są identyczne. Tak mówi standard języka.

Ma to podłoże pragmatyczne: ciało szablonu musi być widoczne w miejscu użycia (o ile nie zdefiniowano gdzieś konkretyzacji dla tego typu, ale to dość rzadko się dzieje), a miejsce użycia może być w różnych plikach .cpp (różnych TU).

0

Ok rozumiem, dzięki!

Co polecasz do poczytania, by wzbogacić wiedzę na temat standardu języka?
Jest coś w przystępnej formie?

0

W przystępnej formie :D Obawiam się, że żądasz za dużo.

Na początku standardem bezpośrednio się nie przejmuj, to zajęcie dla językowych prawników ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1