include einer header geht nicht



  • hallo,

    ich habe eine form erstellt die heißt ViewSreen, in der dazugehörigen ViewScreen.cpp steht folgende Methode:

    #include "StdAfx.h"
    #include "Globals.h"
    #include "OrderedItem.h"
    #include "ProjectFile.h"<<<<<<<<< diesen include bekomme ich nicht fehlerfrei hin
    using namespace PitPlaner;
    
    void ViewScreen::saveToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e){
    ProjectFile ^p;
    p->serializeObject("fileName",Globals::orderedItem);<<<<<<<<zeile 49
    
    }
    

    ohne den include sagt er zum object p warnung unreferenzierte variable
    und wenn man die methode serializeObject aufruft folgendes:

    .\ViewScreen.cpp(49) : error C2027: Verwendung des undefinierten Typs "PitPlaner::ProjectFile"
    e:\c_progs\pitplaner\pitplaner\ViewScreen.h(23): Siehe Deklaration von 'PitPlaner::ProjectFile'
    .\ViewScreen.cpp(49) : error C2227: Links von "->serializeObject" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.

    desshalb habe ich mir gedacht da könnte vll

    #include "ProjectFile.h"
    

    aber dann kommt diese fehlermeldung:

    ViewScreen.cpp
    e:\c_progs\pitplaner\pitplaner\OrderedItem.h(5) : error C2011: 'PitPlaner::OrderedItem': 'class' Typneudefinition
    e:\c_progs\pitplaner\pitplaner\OrderedItem.h(5): Siehe Deklaration von 'PitPlaner::OrderedItem'
    .\ViewScreen.cpp(37) : error C2027: Verwendung des undefinierten Typs "PitPlaner::OrderedItem"
    e:\c_progs\pitplaner\pitplaner\OrderedItem.h(5): Siehe Deklaration von 'PitPlaner::OrderedItem'
    .\ViewScreen.cpp(37) : error C2227: Links von "->Status" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.

    und die klasse OrderedItem sieht so aus:

    namespace PitPlaner{
    	public	ref class OrderedItem
    	{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<zeile 5
    	public:
    		property String^ ProjectName;
    		property String^ Directory;
    		property String^ ImportReportFile;
    		property String^ ImportedFile;
    		property int Status;
    		property int DimX;
    		property int DimY;
    		property int DimZ;
    
    	public: OrderedItem(String ^proName,String ^dir){
    				ProjectName=proName;
    				Directory=dir;
    			}
    			OrderedItem(){
    			}
    
    	};
    }
    

    und zeile 37 in ViewScreen

    Globals::orderedItem->Status
    

    hier auch noch mal ProjectFile.h

    #include "OrderedItem.h"
    
    namespace BBK3PitPlaner{
    
    	public ref class ProjectFile{	
    
    	public:
    		void serializeObject( String^ filename, OrderedItem ^item);
    		void deserializeObject(String ^file);
    	};
    }
    

    in der ViewScreen.h hab ich auch die folgende Vorwärtsdeklaration:
    [code]
    ref class OrderedItem;
    [code]



  • Da fehlen die Include-Guards.



  • Steht am Anfang des Headers ein #pragma once ?



  • von allen headers? nein aber in der ViewScreen ich habe #pragma once hinzugefügt und es klappt. kannst du kurz sagen warum?



  • MFK hat das Stichwort genannt:

    Includeguards.

    Der Präprozessor setzt alles was im Headers steht exakt an die Stelle an der das include steht.

    test.h

    struct t
    {
      int i;
    };
    

    Aus

    #include "test.h"
    
    // bla
    
    #include "test.h"
    

    wird dann:

    struct t
    {
      int i;
    };
    
    // bla
    
    struct t
    {
      int i;
    };
    

    Mit Hilfe der Includeguards kann man den Präprozessor veranlassen, das nur einmal zu machen:

    test.h

    #ifndef TEST_INCLUDEGUARD
    #define TEST_INCLUDEGUARD
    
    struct t
    {
      int i;
    };
    #endif
    

    Aus

    #include "test.h"
    
    // bla
    
    #include "test.h"
    

    wird dann:

    struct t
    {
      int i;
    };
    
    // bla
    

    Das #pragma once macht das gleiche wie der #ifndef #define und #endif Block. Jedoch bequemer aber Compilerspezifisch. (Soll heißen: Funktioniert nur beim VC Compiler (und jene die das nachahmen oder vormachen).

    Vllt. besser erklärt:
    http://www.google.de/search?sourceid=navclient&hl=de&ie=UTF-8&rls=GGLJ,GGLJ:2006-39,GGLJ:de&q=C%2B%2B+Include+guards

    [edit]
    Und nicht vergessen: Ein Header kann auch indirekt includiert werden.

    allgemein.h z.B. wird von speziell1.h und speziell2.h benötigt und die Übersetzungseinheit includiert speziell1.h und speziell2.h . Ohne Includeguards hat man dann allgemein.h zwei mal im Quellcode stehen -> was zu Deinem Problem führt.

    In den seltesten Fällen ist das Verhalten gewünscht, man könnte also sagen: Hau pauschal ein #pragma once an den Anfang Deiner Header.
    [/edit]


Anmelden zum Antworten