[gelöst] Funktion in header -> multiple definition of...

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Spinoza
Beiträge: 23
Registriert: 4. März 2011 01:07

[gelöst] Funktion in header -> multiple definition of...

Beitrag von Spinoza »

Hi,
habe momentan ein kurioses Problem. Ich möchte ein QSet eines enums in/von einem QDataStream schreiben/lesen können. Da Qt von sich aus nicht weiß, dass enums auch nur unsigned ints sind schreibe ich also den Operator<< und >> für dieses enum selbst, und zwar im header(*).

Minimalbeispiel:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDataStream>
#include <QSet>

enum TestEnum {teEins, teZwei};

QDataStream &operator>>(QDataStream &ds, TestEnum &te)
{
  quint16 v;
  ds >> v;
  te = (TestEnum)v;
  return ds;
}

QDataStream &operator<<(QDataStream &ds, const TestEnum &te)
{ (...) }

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow {
(...)
};

#endif // MAINWINDOW_H
Interessanterweise bekomme ich den Fehler:
/usr/include/qt4/QtCore/qdatastream.h:219: multiple definition of `operator>>(QDataStream&, TestEnum&)'
mainwindow.h:13: first defined here
/usr/include/qt4/QtCore/qglobal.h:1372: multiple definition of `operator>>(QDataStream&, TestEnum&)'
mainwindow.h:13: first defined here
:-1: error: collect2: ld returned 1 exit status
obwohl ich ja ein mehrfaches einfügen dieses Headers mittels der defines verhindere. Und was hat überhaupt qglobal.h damit zutun? in Zeile 1372 steht dort code, der nichts offensichtliches mit QDataStream zutun hat.

Jemand 'ne Idee?

(*): Der Fehler tritt natürlich nicht auf, wenn ich die Operatoren im Header nur deklariere und in der .cpp dann implementiere. Da ich diese Operatoren in mehreren Sourcen verwenden möchte, hätte ich sie gerne, inklusive der enum-definition, in einer kompakten header-datei, die ich dann wo immer ich sie benötige einfach includen kann - deswegen auch die Implementierung in einem header.
Zuletzt geändert von Spinoza am 18. Juni 2011 19:22, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Die include-guards sind nur interessant für den Präprozessor, bei dir beschwert sich aber der Linker. Wenn du in mehreren .cpps den Header einbindest, existiert in jeder dieser .cpps eine Definition der Funktion. Werden diese .cpps kompiliert und die Object-Files zu einem Executable gelinkt, findet der Linker (ld bei dir) in jeder der .cpps eine Definition -> multiple definitions.

Lösung: Die Funktionsdefinition als "inline" markieren -> inline davor schreiben. (Googlen wenn du nicht weißt was inline sein soll).
Spinoza
Beiträge: 23
Registriert: 4. März 2011 01:07

Beitrag von Spinoza »

Ah, wieder was gelernt, vielen Dank.
Hat ein explizites inline also doch noch eine Daseinsberechtigung. ;)
Antworten