2 Stimmen

String-Prototyp im Header benötigt iostream?

Also in meinem Header habe ich einen String erstellt: string s; Der Compiler flippt dabei aus. Ich weiß, dass string Teil von iostream::std ist. Muss ich es also im Header anstelle der .cpp-Datei einfügen? Wenn ja, ist es schlimm, wenn andere Dateien, die den Header verwenden, iostream einfügen? Wie gehe ich damit um?

Bearbeitung: Auch für Vektoren, da es scheint, dass ich sie in meiner Aufgabe viel brauchen werde.

Bearbeitung 2: Ich erinnere mich daran, in vielen Beispielen von Headern #ifndef gesehen zu haben, und ich glaube, dass es bei meiner Frage helfen könnte, aber ich finde keine gute Erklärung.

5voto

Chad Punkte 17801

string und vector sind getrennt von iostream, und alle drei gehören zum std Namespace. Sie müssen sie nur ordnungsgemäß in Ihren Header-Dateien qualifizieren.

Assignment.h

 #include 
 #include 
 // kein Bedarf für #include 

 struct Obj
 {
    // voll qualifiziert mit std::
    std::string s_;

    // dasselbe:
    std::vector v_;
 };

2voto

Luchian Grigore Punkte 244505

Es ist in Ordnung, Überschriften in anderen Überschriften einzuschließen, wenn Sie sie benötigen und keine zyklischen Abhängigkeiten erstellen. Dies ist hier nicht der Fall, da keine benutzergenerierte Überschrift ist.

Schlecht wäre es, wenn Sie using namespace std; zu Ihrem Header hinzufügen würden, anstatt den Gültigkeitsbereich Ihrer Typen anzugeben. Dadurch wird Ihr globaler Namespace mit den Inhalten von namespace std in allen Dateien gefüllt, in denen Sie Ihren Header einbeziehen.

0voto

Jon Punkte 411383

Natürlich müssen Sie den Header für string inkludieren, wenn Sie es in Ihrem eigenen Header verwenden. Dies liegt daran, dass der Compiler das Speicherlayout des Objekts berechnen muss, das ein string-Element hat, was bedeutet, dass er zuerst das Layout von string berechnen muss, was bedeutet, dass er die vollständige Deklaration von string sehen muss.

Es gibt keinen direkten Weg um dies herum, aber wenn es ein Problem für Sie ist, können Sie dies umgehen, indem Sie das Pimpl-Idiom verwenden. Einer der Vorteile dieses Musters ist, dass Sie ein Objekt in Ihrer Klasse aggregieren können, ohne die Notwendigkeit zu haben, zuerst dessen Deklaration einzuschließen (anstatt dieser Klasse eine Vorwärtsdeklaration vorzunehmen) wie folgt:

class std::string; // Vorwärtsdeklaration

class my_class
{
    std::string* psz;
};

Natürlich sind Sie nun dafür verantwortlich, einen string zu konstruieren und einen Zeiger darauf zu erhalten, und auch dieses Objekt manuell zu verwalten. Darüber hinaus erfordert der Zugriff auf diesen String nun eine zusätzliche Zeigerdereferenzierung.

0voto

ks1322 Punkte 31216

Ja, du musst einbeziehen, weil std::string tatsächlich ein typedef für das basic_string Template ist.

typedef basic_string string;

Wenn es eine Klasse wäre, könntest du sie in einigen Fällen ohne Einbeziehung der Definition vorwärts deklarieren.

class string;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X