Aufrufen einer Funktion von einer anderen classe



  • Soljer schrieb:

    @natham und wie erstelle ich so eine "freie funktion" ?

    Kommst du von einer strikten OOP Sprache?

    namespace Logger {
        void info(const std::string& message); // impl wie vorher
        // ref hinzugefügt um kopieren zu vermeiden.
    }
    

    (hier kann man evtl darüber nachdenken info etwas ausdrücklicher zu bennen, wie zb printInfo)

    oder als statische Funktion in der Klasse Logger (das Beispiel habe ich wieder entfernt, weil wenn eine Klasse nur statische Funktionen enthält schreit das nach "NAMESPACE")

    Wenn der Logger state braucht, dann ein Singleton. Aber das lasse ich mal weg, es sei denn du fragst danach. Ich bekenne mich schuldig meine Logger gerne als Singleton zu modellieren.



  • "Freie Funktion" heißt außerhalb der Klasse.
    Du kannst aber auch eine statische Klassenmethode erstellen:

    class Logger
    {
    public:
        static void info(const std::string message);
    };
    

    Und Aufruf dann

    Logger::info("Log created");
    

    Ist besser lesbar als nur eine freie Funktion "info" oder aber du nennst sie "logger_info" oder "log_info" o.ä.

    Edit: oder aber auch innerhalb eines Namensbereichs (namespace), wie mein Vorposter geschrieben hat...



  • Mir gefällt die Lösung mit den statischen Klassenmethoden auch am besten.



  • Doch wie kann ich die Klasse "logger" aufrufen ohne vorhin irgendetwas in meiner main datei hinzugefügt zu haben.

    Logger::info ist mir bekannt doch ich möchte auch nicht statische aufrufen.



  • Gar nicht.
    Für eine Memberfunktion musst du ein Objekt erzeugt haben. Ohne Objekt gehen nur statische oder freie Funktionen.



  • Wenn du eine Klasse mit statischen Methoden definierst, dann muss du kein Objekt von dieser KLassen instanzieren. Wenn du die Klasse als Singleton anlegst, dann muss du wenigstens einmal ein Objekt davon erzeugen, beim nächsten Erzeugen wird aber immer wieder die gleiche erste Instanz zurückgegeben.

    Wenn du Variablen, Funktionen, Klassen und deren Methoden nutzt, dann müssen die irgendwo definiert worden sein. Entweder direkt in deiner Datei mit main drinn, oder in einer anderen Datei, die du dann inkludierst. Sie kann auch nur definiert sein, also der Prototyp wurde bekannt gemacht und der Linker kümmert sich dann darum, dass die richtig Adresse angesprungen wird. Wie dem auch sei, irgendwo muss es eine Definition und eine Deklaration geben und die muss den Weg nach main schaffen, entweder direkt in main oder in einer externen Datei die du dann einbinden und eventuell extra Linken musst. Ein Include ist wie ein Copy&Paste im Texteditor, nur dass man noch mit der Makrosprache eingreifen kann.



  • Achso, wäre es dann irgendwie auch möglich in meiner main datei eine Instance zu erstellen, womit ich dann dn logger und viele andre sachen aufrufen könnte?

    ServerInstance->logger->log("Logged");



  • Wie instanzierst du denn sonst deine Objekte von den Klassen?



  • #include <server.h>
    #include <logger.h>
    
    Server *ServerInstance = NULL;
    
    Server::Server()
    {
    	ServerInstance = this;
    	/* ::: */
    }
    


  • Nein, ich meine wie instanzierst du in deiner Main-Methode ein Objekt, denn das war doch deine ursprüngliche Frage oder?

    Eine Möglichkeit deine Loggerklasse zu nutzen wäre diese:

    logger.h

    #ifndef LOGGER_H
    #define LOGGER_H
    #include <string>
    
    class Logger
    {
    public:
        void info(const std::string message);
    };
    
    #endif // LOGGER_H
    

    logger.cpp

    #include "logger.h"
    #include <iostream>
    
    void Logger::info(const std::string message) //TODO
    {
        std::cout << "[INFO]" + message << std::endl;
    }
    

    main.cpp

    #include "logger.h"
    
    int main()
    {
        Logger log;
        log.info("Test");
        return 0;
    }
    

    Ausgabe:

    [INFO]Test
    


  • Doch das Problem ist, ich will den Logger auch in mehreren Klassen verwenden.
    Wenn ich ihn in anderen verwende also die "Logger log;" methode gibt mein MinGW-4.8.1 compiler einen fehler aus reciepe failed....

    edit: Ich müsste in jeder datei meinen Logger anderst nennen also nicht Logger log sonder das log müsste immer unterschiedlich benannt sein, deswegen würdde ich eine andere Methode bevorzugen. Vllt mit einem #Define ?



  • Soljer schrieb:

    Doch das Problem ist, ich will den Logger auch in mehreren Klassen verwenden.
    Wenn ich ihn in anderen verwende also die "Logger log;" methode gibt mein MinGW-4.8.1 compiler einen fehler aus reciepe failed....

    Volle Fehlermeldung und Code bitte.

    edit: Ich müsste in jeder datei meinen Logger anderst nennen also nicht Logger log sonder das log müsste immer unterschiedlich benannt sein, deswegen würdde ich eine andere Methode bevorzugen.

    Wieso?



  • C:/.../.../src/anderedatei.cpp:31: multiple definition of `logger'



  • Soljer schrieb:

    C:/.../.../src/anderedatei.cpp:31: multiple definition of `logger'

    Code dazu bitte.
    Ich rate mal: Du verwendest globale Variablen. Und das auch noch falsch.



  • Das bedeutet, du hast Logger mehrmals definiert. Man darf nur einmal definieren, deklarieren darfst du mehrmals. Da wo du Logger nutzen willst, musst du nur die Header-Datei, also die Deklaration, inkludieren. Dann kannst du in deinen anderen Klassen auch die Logger Klasse einbauen und nutzen. Vielleicht magst du noch mehr Code posten, denn raten ist immer so ne Glückssache?



  • Ich versteh nicht, was jetzt das Problem sein soll. Funktioniert doch einwandfrei:

    #include <iostream>
    #include <string>
    
    class Logger {
    public:
        static void info(const std::string& message)
        {
            // weiß jetzt nicht, ob std::endl hier tatsächlich sinnvoll wäre
            std::cout << "[INFO] " << message << '\n';  
        }
    };
    
    class Foo {
    public:
        Foo() { Logger::info("Foo instance created."); }
    };
    
    int main()
    {
        Logger::info("Program started.");
        Foo myFoo;
    }
    


  • Ja, das wäre dann die Version mit statischer Methode, wo zu deren Nutzung kein Objekt extra instanziert werden muss. Mich würde aber auch mal interessieren womit er jetzt noch Probleme hat. Ich vermute mal die Grundlagen sitzen da noch nicht so richtig und die sollte er mit Minimalbeispielen trainieren, also alles was nicht zum Problem gehört isolieren.


Anmelden zum Antworten