Linkerfehler
-
Andreas_L schrieb:
...ich denke aber, das ein Include Guard dabei ist...
=>
Andreas_L schrieb:
...
Jetzt meckert aber der Compiler:
C:\Dokumente und Einstellungen\Andy\Desktop\dfghsdgh\Header1.cpp(4) : error C2086: 'Zahlen' : redefinition
...Offensichtlich nicht.

"include guard" ist kein Feature eines C++-Compilers, sondern eine Programmiertechnik (sprich: "Etwas, das Du in Deinem Source machen musst"), die genau solche "Redefinitions" verhindert.
In Deinem Fall würde ich Folgendes machen:
- globale Variablen vermeiden (Hier: "Zahlen")
- ... erst Recht in Headern,
- "precompiled Headers" abschalten (in Deiner "Visual Studio"-Entwicklungsumgebung) und
- Jeden Header mit folgendem Block einfassen:
#ifndef HEADERNAME_INCLUDE_GUARD #define HEADERNAME_INCLUDE_GUARD // .... Hier kommt dann Dein Source #endif // HEADERNAME_INCLUDE_GUARDLetzteres ist Dein "Include Guard" ("HEADERNAME" sollte natürlich für den Namen des jeweiligen Headerfiles stehen und nicht überalle gleich heißen).
Gruß,
Simon2.
-
Danke,
jetzt siehts so aus:#ifdef HEADER1_INCLUDE_GUARD #define HEADER1_INCLUDE_GUARD struct wichtig { int Zahl; }Zahlen; class Header1 { void Funktion(); void Funktion3() { int Zahl = Zahlen.Zahl; } }; #endif // HEADER1_INCLUDE_GUARDund
#ifdef HEADER2_INCLUDE_GUARD #define HEADER2_INCLUDE_GUARD extern wichtig Zahlen; class Header2 { void Funktion(); void Funktion3() { int Zahl = Zahlen.Zahl; } }; #endif// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #ifdef StdAfx_INCLUDE_GUARD #define StdAfx_INCLUDE_GUARD #if !defined(AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_) #define AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include <stdio.h> #include "Header1.h" #include "Header2.h" #endif // TODO: reference additional headers your program requires here //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_)An den Cpp-Dateien hat sich ja nichts verändert.
Jetzt meckert er in den Cpp datein immer:
C:\Dokumente und Einstellungen\Andy\Desktop\dfghsdgh\Header1.cpp(4) : error C2146: syntax error : missing ';' before identifier 'Zahlen'#include "StdAfx.h" wichtig Zahlen; void Header1::Funktion() { int jj; jj = Zahlen.Zahl; }Du meintest, dass man möglichst keine Globalen Variablen machen sollte.
Aber was soll man machen, wenn eine Struktur von mehreren Klassen verwendet wird?
Mit der obigen Änderung hab ich dann aber doch ein Include-Guard, oder nciht?
Gab es nicht auch soetwas mit #pragma once?Was muss man denn jetzt noch machen, damit er das endlich komplett übersetzt?
Viele Grüße
Andreas
-
Die extern-Deklaration gehört ja auch in den Header:
struct wichtig { int Zahl; } extern wichtig Zahlen; class Header1 { ... };(noch besser ist es natürlich, wenn du auf die externe Variable komplett verzichtest)
-
Danke, aber irgendwie klappt jetzt gar nichts mehr:
In die Headerdateien sollte der Includeguard. zudem sollte dort die Variable mit extern definiert werden:
#ifdef HEADER1_INCLUDE_GUARD #define HEADER1_INCLUDE_GUARD struct wichtig { int Zahl; }; extern wichtig Zahlen; class Header1 { void Funktion(); void Funktion3() { int Zahl = Zahlen.Zahl; } }; #endif // HEADER1_INCLUDE_GUARDund
#ifdef HEADER2_INCLUDE_GUARD #define HEADER2_INCLUDE_GUARD extern wichtig Zahlen; class Header2 { void Funktion(); void Funktion3() { int Zahl = Zahlen.Zahl; } }; #endifIn die CPP Dateien sollte ich doch wichtig Zahlen reinschreiben:
#include "StdAfx.h" wichtig Zahlen; void Header1::Funktion() { int jj; jj = Zahlen.Zahl; }und
#include "StdAfx.h" wichtig Zahlen; void Header2::Funktion() { int JJ = 3; JJ = Zahlen.Zahl; }Bei stdafx.h hab ich das einfach so belassen, wie es bei Mircrosoft vorgegeben wurde:
// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_) #define AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include <stdio.h> #include "Header1.h" #include "Header2.h" // TODO: reference additional headers your program requires here //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__0B335010_3D3D_4528_892F_2AE1F3666FF2__INCLUDED_)Die Probleme bleiben aber immer noch:
C:\Dokumente und Einstellungen\Andy\Desktop\dfghsdgh\Header1.cpp(4) : error C2146: syntax error : missing ';' before identifier 'Zahlen'Wenn ich dann Zahlen auskommentiere kommt:
C:\Dokumente und Einstellungen\Andy\Desktop\dfghsdgh\Header1.cpp(6) : error C2653: 'Header1' : is not a class or namespace name
Das deutet doch dann darauf hin, dass Header1.h überhaupt nicht mehr eingebunden wurde oder nicht?
Ich hatte in der ersten Headerdatei nicht extern davor geschrieben, weil ich extern so verstanden habe, dass der nur darauf verweist, dass die Variable woanders definiert wird. In Header1 wird sie aber definiert, deshalb dachte ich muss man extern da weglassen.
Viele Grüße
Andreas
-
Erstens: Du sollst in EINER CPP-Datei die Variable definieren.
Zweitens: In Header2 ist der Typ "wichtig" nicht bekannt, da macht die Definition Probleme.
PS: Wofür soll die Variable 'Zahlen' eigentlich gut sein?
-
HI, die Variable Zahlen sollte einfach nur als Beispiel dienen.
In meinem realen Projekt habe ich nämlich eine Struktur, in der VerkaufsPreise definiert werden.
Zu Beginn werden diese Preise aus einer INI-Datei ausgelesen und in der Struktur gespeichert.
Nun sollen die verchiedenen Klassen darauf zugreifen können, deshalb sollte eine globale Variable vorhanden sein, auf die jede Klasse einfach zugreifen kann.
Ich hab jetzt die Variablen als Member gemacht, damit gehts, hätte micht nur mal interessiert, warum sich der Linker immer beklagt.Eine letzte Frage noch:
Bisher hab ich keinen IncludeGuard verwendet und es gab keine Compilerfehler.
Muss ich das trotzdem noch ändern, weil so wie ich den IncludeGuard eben hatte ging es ja nicht.Viele Grüße
Andreas
-
Der Linker beschwert sich, weil die selbe Variable in mehreren Übersetzungseinheiten definiert wurde - und er jetzt nicht weiß, welches die "richtige" ist.
Ich würde übrigens die wichtig-Klasse mit allem in eine eigene Datei auslagern, anstatt sie an eine der Header-Klassen anzuhängen (in der nächsten Entwicklungsstufe sogar als Singleton angelegt:
//wichtig.h struct wichtig { int Zahl; }; extern wichtig Zahlen; //wichtig.cpp #include "wichtig.h" wichtig Zahlen //HeaderX.h #include "wichtig.h" class HeaderX { ... }; //HeaderX.cpp #include "HeaderX.h" ... //main.cpp #include "Header1.h" #include "Header2.h" int main() {...}
-
Danke, werd mal gucken wie ich das so umsetzen kann

-
Was vielleicht auch nicht ganz unwichtig ist:
#ifndef (if not defined)
statt
#ifdef (ifdef)
oder aber die Variante von (D)evil, welche ich persönlich noch nicht ausprobiert habe.
Grüße...
Heiko
-
bwbg schrieb:
Was vielleicht auch nicht ganz unwichtig ist:
#ifndef (if not defined)
...

Oh ja !! Sorry !!!Mein Fehler,
Simon2.