Interaktion zwischen Objekten.



  • Danke für die schnelle Antwort. Werde ich mal testen.

    Natürlich heißt die Methode nicht main, war nur ein Beispiel; Aber zugegeben ein ziemlich Blödes 😉



  • Hallo,

    funktioniert leider so nicht...

    // TestForwardDeklaration.h
    
    #pragma once
    
    using namespace System;
    
    namespace TestForwardDeklaration {
    
    	public ref class Init
    	{
    	public:
    		TestForwardDeklaration::Formular^ Form1;
    
    		Init();
    		void Message(String^ text);
    	};
    }
    
    //TestForwardDeklaration.cpp
    // Dies ist die Haupt-DLL.
    
    #include "stdafx.h"
    #include "Formular.h"
    #include "TestForwardDeklaration.h"
    
    TestForwardDeklaration::Init::Init() {
    	Form1 = gcnew Formular(this);
    }
    
    void TestForwardDeklaration::Init::Message(String^ text) {
    	MessageBox::Show(text);
    }
    
    //Fourmular.h
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    namespace TestForwardDeklaration {
    
    	//Forward Deklaration
    	ref class Init;
    
    	/// <summary>
    	/// Zusammenfassung für Formular
    	///
    	/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
    	///          die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
    	///          das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
    	///          Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
    	///          arbeiten, die diesem Formular zugewiesen sind.
    	/// </summary>
    	public ref class Formular : public System::Windows::Forms::Form
    	{
    	public:
    		Formular(Init^ Parent)
    		{
    			InitializeComponent();
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    			Parent->Message("test");
    		}
    ...
    
    //Fourmular.cpp
    
    #include "StdAfx.h"
    #include "Formular.h"
    

    Alle Anderen Dateien sind wie von VS2005 erstellt.

    Fehler 1 error C2027: Verwendung des undefinierten Typs "TestForwardDeklaration::Init" c:\_intern\coding\projekte\testforwarddeklaration\testforwarddeklaration\Formular.h 34
    Fehler 2 error C2227: Links von "->Message" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden. c:\_intern\coding\projekte\testforwarddeklaration\testforwarddeklaration\Formular.h 34

    Liegt das am managed code? Oder hab ich da noch nen Anderen Fehler drin?



  • Nein, das liegt daran, daß du die falsche Klasse Forward deklariert hast. Die Klasse 'Init' muß wissen, daß es eine Klasse 'Formular' gibt, also mußt du es ihr auch sagen.



  • Sorry ich steh aufm Schlauch.

    Wie sieht das dann in diesem Beipiel richtig aus?

    MainObj -> erstellt Formular und gibt Refernz auf sich selbst mit.
    Formular -> soll im Konstruktor auf eine Methode von MainObj zugreifen.

    Ich verteh das Prinzip noch nicht ganz.

    Es gibt da zwei Varianten:
    Objekt2 wurde in Objekt1 erstellt und soll auf Mehtoden von Objekt1 zugreifen (wie oben)
    Objekt1 und Objekt2 sind absolut unabhängig und bekommen während der Laufzeit die Refernz auf das jeweillig andere Objekt zugewiesen und können dann gegenseitig Methoden aufrufen.



  • In dem Fall hängt es von der Reihenfolge der eingebundenen Header ab, wer eine Forward Deklaration benötigt - Die Klasse, die als erstes kommt, braucht eine Deklaration ihrer Partnerklasse (für die zweite Klasse steht ja schon die Definition da). Aber auf der sicheren Seite bist du, wenn du für beide Klassen eine Forward Deklaration hinsetzt:

    //MainObj.h
    class Formular;
    
    class MainObj
    {
    public:
      Formular* form;
      void init();
      void run();
      void print(std::string test) {cout<<test<<endl;}
    };
    
    //MainObj.cpp
    #include "MainObj.h"
    #include "Formular.h"
    
    void MainObj::init()
    {
      form = new Formular(this);
    }
    
    void MainObj::run()
    {
      form->calculate();
    }
    
    //Formular.h
    class MainObj;
    class Formular
    {
      MainObj* parent;
    public:
      Formular(MainObj* p);
      void calculate();
    }
    
    //Formular.cpp
    #include "Formular.h"
    #include "MainObj.h"
    
    Formular::Formular(MainObj* p) : parent(p) {}
    
    void Formular::calculate()
    {
      parent->print("Dies ist ein Test");
    }
    


  • Ahh, danke.

    Ich hab mir das jetzt so umgebaut:

    // stdafx.h : Includedatei für Standardsystem-Includedateien
    // oder häufig verwendete projektspezifische Includedateien,
    // die nur in unregelmäßigen Abständen geändert werden.
    
    #pragma once
    #include "class1.h"
    
    #include "form1.h"
    #include "form2.h"
    
    #include "maincode.h"
    
    // stdafx.cpp
    #include "stdafx.h"
    
    namespace dll {
    
    	// forward declaration
    	// Libs
    	ref class class1;
    	// Forms
    	ref class form1;
    	ref class form2;
    	// Main
    	ref class maincode;
    }
    
    // maincode
    #include "stdafx.h"
    
    namespace dll {
    	public ref class maincode {
                ...
            };
    }
    

    Die Namen sind natürlich beispielhaft zu verstehen. 😉

    Macht man das eigentlich prinzipiell so, oder nur nach Bedarf?



  • Also in der stdafx.cpp sind die Forward's auf jeden Fall fehl am Platz, schlißlich wird die erstens nirgends eingebunden (und in anderen Übersetzungseinheiten erfährt der Compiler nichts davon) und hat zweitens über die stdafx.h schon die kompletten Definitionen erhalten. Die Forward Deklarationen benötigst du in der maincode.h etc, bevor du die Nachbarklassen verwenden kannst.



  • Die stdafx.cpp ist eigentlich nur eine Dummy-Datei, da schreibt man nichts rein.



  • Hoi, gut zu wissen.

    Aber...
    Also wenn ich nen Formular anlege, dann schreibt das VS2005 ja standardmässig
    #include "StdAfx.h" in die cpp-Datei des Formulars, bzw. in die cpp-Datei eines neuen Projekts.

    Und aufgrund der Info in der "stdafx.h" bin ich mal davon ausgegangen, dass die Datei genau für so etwas da ist.

    // stdafx.h : Includedatei für Standardsystem-Includedateien
    // oder häufig verwendete projektspezifische Includedateien,
    // die nur in unregelmäßigen Abständen geändert werden.
    

    Hat eingetlich ganz gut funktioniert so. Aber man kann es ja genau so in die Dateien (.cpp/.h) des eigentlichen Codes packen.



  • Also in die stdafx.h kannst du ja was reinschreiben, halt Header-Dateien die du öffters in deinem Projekt verwendest und die z.B. komplex sind (STL-Header sind komplex oder die windows.h ist riesig). Aber die stdafx.cpp ist ein Dummy, die mußt du so lassen wie sie ist (da fehlt leider ein autom. generierter Kommentar nach dem Motto "Diese Datei darf nicht geändert werden!").


Anmelden zum Antworten