wo lege ich eine instanz einer klasse an?



  • hi Leute
    Ich möchte von allen Fenstern (also Hauptfenster und Childs) auf eine Instanz (Graph) einer Klasse (CGraph) zugreifen können.
    Jetzt weiss ich nicht, wo ich die Instanz erzeugen soll.

    Möglichkeiten:
    (1)

    class CppAppWnd{ 
    ... 
    public: CGraph Graph; 
    ... 
    };
    

    Wenn es eine Member der Haupt-Fenster-Klasse ist, hab ich aber Mühe, die Klasse "anzusteuern", da die Instanz der Haupt-Fenster-Klasse im "Start-File" (-siehe unten-) erzeugt wird. Deshalb habe ich diese Instanz im Child-Wnd nicht zur Verfügung.

    (2)

    //im header graph.h
    class CGraph{
    ...
    };
    static CGraph Graph;
    

    So kann ich vom Hauptfenster zugreifen, d.h. verändern und abrufen. Vom Child-window her geht das nicht, ich erhalte also im CScrollWnd.cpp bei Abfragen von Graph immer die Standardwerte (also zb. "" bei einem string).

    (3)

    //..?..
    

    Das "Start-File" meines Projekts: http://www.xmail.net/nate7/files/Source_WinMainStart_cpp.html
    Die ganze übersicht: [url]http://www.xmail.net/nate7/sourcecode_all.html[url]
    (schönes design gibts aber nur auf den parent-sites.. :D)

    dankeschön für tipps!



  • Ich würde eine Singleton-Klasse erstellen, die ein Objekt der Klasse CGraph kapselt.

    //Header
    class TheOneAndOnlyGraph
    {
    public:
      static bool Init();
    
      static CGraph& RequestGraph();
    
    private:
      TheOneAndOnlyGraph(const TheOneAndOnlyGraph&){};
      TheOneAndOnlyGraph& operator =(const TheOneAndOnlyGraph&){};
      TheOneAndOnlyGraph()
      {}
      ~TheOneAndOnlyGraph()
      {}
    private:
      static TheOneAndOnlyGraph *ms_pSingleton;
      CGraph m_Graph;
    };
    
    //Source
    TheOneAndOnlyGraph *TheOneAndOnlyGraph::ms_pSingleton = NULL;
    
    bool TheOneAndOnlyGraph::Init()
    {
      // Does the singleton already exist?
      if( ms_pSingleton )
        true;
    
      ms_pSingleton = new TheOneAndOnlyGraph();
    
      if( !ms_pSingleton )
        return false;
    
      //Additional Code..
    }
    
    CGraph& TheOneAndOnlyGraph::RequestGraph()
    {
      assert(ms_pSingleton);
      return ms_pSingleton->m_Graph;
    }
    

    Mit einem Singleton hast du eine Klasse auf die du praktisch von überall zugreifen kannst; so ähnlich wie eine globale Variable eben, nur mit Methoden der OOP implementiert.



  • dankeschön! sieht nicht schlecht aus.. werds grad ausprobieren
    aber.. ginge das nicht auch einfacher?



  • 🙂 wunderbar!! das funktioniert ja (okee.. sonst hättest du es wohl nicht gepostet..:D)

    nur noch ein detail:

    TheOneAndOnlyGraph::RequestGraph().getPathName();
    

    es widerstrebt mir etwas, jedes mal sone lange Geschichte zu schreiben (das mach ich jetzt bei jedem Aufruf von "Graph")
    ist das 1. nötig, 2. sinnvoll, 3. nicht unglaublich langsam?



  • 1.) Wenn du ein Singleton verwenden willst, dann schon.
    2.) Sinnvoller als "C-like" globale Variablen würde ich sagen.
    3.) Sollte eigentlich ziemlich schnell sein. Erstens wird ja eine Referenz zurückgegeben und zweitens ist es eine einzeilige Inline-Funktion (zumindest im Release-Modus).

    Du kannst zwischen zwei Möglichkeiten wählen wenn dir solche Funktionsaufrufe zu lang sind.

    1.) Gleich zu Beginn bevor du das Objekt benötigst deklarierst du eine Referenzvariable, die du mit der Singleton-Klasse initialisierst:

    Graph &graph = TheOneAndOnlyGraph::RequestGraph();
    
    graph.getPathName();
    

    2.) Du versuchst einfach einen kürzeren Namen für die Singleton-Klasse und die Getter-Funktion auszuwählen. TheOneAndOnlyGraph war eigentlich etwas übertrieben gewählt; ich hätte nicht gedacht, dass du es 1:1 übernimmst 😃

    //Vielleicht ist folgendes besser:
    GraphManager::Graph().getPathName();
    


  • Wo wird bei deinem Code delete aufgerufen?



  • delete?! schrieb:

    Wo wird bei deinem Code delete aufgerufen?

    Gegenfrage, wo wird "new" aufgerufen?



  • MiC++ha schrieb:

    Gegenfrage, wo wird "new" aufgerufen?

    ich würd mal sagen hier

    Aziz schrieb:

    [cpp]
    [cpp]
    bool TheOneAndOnlyGraph::Init()
    {
    // Does the singleton already exist?
    if( ms_pSingleton )
    true;

    ms_pSingleton = new TheOneAndOnlyGraph();

    if( !ms_pSingleton )
    return false;

    //Additional Code..
    }



  • Stimmt!
    Das hatte ich übersehen.





  • dankeschön für die antworten, speziell für den link!

    @Aziz: ach weisst du, das mit dem TheOneAndOnlyGraph hat mir grad so gefallen, da hab ichs grad so übernommen.. 😉 (ist mal son richtig aussagekräftiger class-name)



  • delete?! schrieb:

    Wo wird bei deinem Code delete aufgerufen?

    Eine sehr gute Frage 😃

    Eine Methode zu schreiben, welche die Instanz freigibt wäre empfehlenswert 😃



  • oder die instanz mit dem schlüsselwort static erstellen wie in dem link gezeigt ist



  • Natürlich, so kann man es auch implementieren. Der Vorteil meiner Version ist jedoch - sofern man es benötigt, dass man den Zeitpunkt der Konstruktion sowie den Zeitpunkt der Destruktion des Singletons kontrollieren kann.



  • Genau 🙂



  • [edit][/edit]


Anmelden zum Antworten