2012-03-29 4 views
2

Ich habe 4 Dateien:C++ Variable von 2 Dateien geteilt

  • SHARED.H
  • main.cpp
  • something.h
  • something.cpp

geteilt. h:

#ifndef SHARED_H 
#define SHARED_H 

int* sth; 

#endif 

something.h:

#ifndef SOMETHING_H 
#define SOMETHING_H 

class foo 
{ 
    public: 
     void printVar(); 
}; 

#endif 

something.cpp:

#include <iostream> 
#include "something.h" 
#include "shared.h" 

using namespace std; 

void foo::printVar() 
{ 
    cout<<"Foo: "<<*sth<<endl; 
}; 

main.cpp:

#include <cstdlib> 
#include <iostream> 
#include "shared.h" 
#include "something.h" 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    sth=new int(32); 

    foo x; 
    cout<<"Main: "<<*sth<<endl; 
    x.printVar(); 

    system("PAUSE"); 
    return EXIT_SUCCESS; 
} 

Compiler zurück multipe Definition * etw;

Ich habe den * sth statischen Modifier hinzugefügt und es kompiliert, aber stürzt ab. Ich habe die Aufdrucke die Adressen der Zeiger zu drucken und ich hatte Programm zurückgegeben:

Main: 0x3e0f20 
Foo: 0 

Warum ist der Zeiger foo nicht zugewiesen? Ich möchte es nur einmal in main zuweisen und dann in anderen Dateien teilen ... Wie kann ich das machen? Ist es etwas mit extern Modifikator?

Danke für alle Antworten.

Antwort

4

Ja, verwenden Sie extern. Setzen Sie extern int* sth; in die Kopfzeile und dann in eine der Quelldateien setzen int* sth;.

extern teilt dem Compiler und Linker mit, dass sich die tatsächliche Variable/Funktionsdefinition in einer anderen Kompilierungseinheit (d. H. Einer anderen Quelldatei) befindet.

+0

Sie waren zuerst, also akzeptiere ich Ihre. –

5

In SHARED.H möchten Sie sagen:

extern int* sth; 

den Compiler versprechen, dass etw irgendwo existiert.

Dann in einem (und man nur) der CPP-Dateien müssen Sie schreiben:

int* sth; 

Um es tatsächlich existiert. Im Allgemeinen möchten Sie wahrscheinlich über the difference between declaration and definition lesen. Als Faustregel wollen Sie nur Dinge in Header-Dateien deklarieren, nicht definieren.

Wenn Sie schreibt static zuvor gesagt, dass eine Variable mit dem gleichen Namen in jeder Datei existiert, ist aber „lokal“ zu jedem, dh die sth in main.cpp nicht das gleiche wie die sth in etwas sein wird. cpp.

+0

und in anderen Dateien sollte ich auch extern verwenden oder nicht? –

+0

@kittyPL in anderen Dateien '# include' mit der Header-Datei ist ausreichend. Das "Extern" ist ein Versprechen an den Compiler, dass es irgendwo existieren wird, wenn es benötigt wird. Das 'int * sth' ohne' extern' macht es tatsächlich an diesem bestimmten Ort existieren. Sie können 'extern int * etw so oft schreiben, wie Sie möchten, aber es ist sicherer, es nur einmal in eine einzige Header-Datei zu schreiben. – Flexo

+0

[Linker Fehler] undefinierter Verweis auf 'sth '... was nun? Es passiert in der Datei ohne int * sth; Gleiches mit externem int * etw. –

2

Sie benötigen sth als extern in der Kopfzeile markieren eine Erklärung, zu machen und eine Definition für sie in einem der CPP-Dateien bieten.Andernfalls lautet die Variable in jeder Kompilierungseinheit, in der die Kopfzeile enthalten ist,, was nicht der gewünschte Effekt ist.

P.S. Ich nehme an, dass Sie wissen, warum globale Variablen sind nicht gut, oder?

1

Sie möchten es nicht als statisches globales Element erstellen, da es in jeder Übersetzungseinheit ein lokales sth erzeugt und Sie es nur in einem zuweisen. Aus diesem Grund stürzte es in Foo::printVar ab, da es in diesem Bereich ein nicht initialisierter Zeiger war.

Sie möchten es als extern int* sth; im freigegebenen Header deklarieren und dann int* sth; vor oder mindestens an einer Stelle, bevor es verwendet wird.

Eigentlich, wenn Sie wirklich benötigen ein global zugängliches Objekt, auf dem Heap zugeordnet, und Sie es dann teilen möchten, kann es besser sein als extern std::shared_ptr<int> sth;. Definieren Sie es als std::shared_ptr<int> sth; auf die gleiche Weise in einer der CPP-Dateien und rufen Sie std::make_shared, um es zuzuweisen. Auf diese Weise wird die Speicherfreigabe automatisch aufgehoben, wenn das letzte Objekt, das es verwendet, den Gültigkeitsbereich verlässt.

2

"Ich habe 4 Dateien".

Lassen Sie mich Sie dort stoppen. Ich stimme zu, dass Sie vier Dateien haben, aber das ist nicht wirklich relevant. Sie haben zweiÜbersetzungseinheiten. Eine Übersetzungseinheit ist die Menge an Text, die in Ihren Compiler eingespeist wird. Ihre Übersetzungseinheiten nennen wir sie MAIN und SOMETHING, bestehen aus dem Ergebnis der Vorverarbeitung Ihrer Dateien main.cpp bzw. something.cpp.

Nach Vorverarbeitung, jede Ihrer Übersetzungseinheiten enthält eine Zeile int *sth; Diese Zeile deklariert und definiert die Variable sth.

Die One-Definition-Regel erfordert, dass Sie in Ihrem gesamten Programm genau eine (nicht mehr, nicht weniger) Definition von sth haben. Um dies zu erreichen, müssen Sie genau eine Quellcodezeile int *sth; in genau einer Übersetzungseinheit und so viele haben, wie Sie benötigen.

In Ihrem Fall würde ich setzen int *sth; in MAIN und in ETWAS. Zusätzlich können Sie so viele zusätzliche Kopien von haben, wie Sie möchten - sie werden nichts verletzen.

Jetzt zurück zu Ihren vier Dateien. Sie sollten in shared.h setzen. Dies bedeutet, dass MAIN und SOMETHING beide eine extern Zeile haben. Sie sollten auch int *sth; in main.cpp setzen, damit MAIN die Definition hat.

Und da sind Sie: MAIN und ETWAS haben beide extern Zeilen, so dass sie sich beide auf die gleiche Variable beziehen. MAIN hat auch eine Definition. also die sth Variable hat genau eine davon.


Neben: Warum static int *sth; in shared.h die falsche Sache tun?

Da jede der beiden Übersetzungseinheiten ihre eigene static Erklärung sehen. Eine static Deklaration reduziert die Verknüpfung des deklarierten Namens mit dieser einzelnen Übersetzungseinheit.