Abfragen ob Klasse existiert



  • Sehr witzig 🤡
    Das jetzt ein übertragenes Beispiel für den CBuilder. Dort gibt es "Formen", also eine Klasse welche die Elemente wie Eingabefelder und Button verwaltet. Ich möchte nun gern wissen ob die Klasse bzw die TForm10 in das Projekt eingebunden ist oder nicht, um mein Menü gestalten zu können. Wenn sie nicht eingebunden ist ins Projekt, dann soll es den Menüpunkt nicht geben, wenn vorhanden, dann soll es den Menüpunkt natürlich geben.

    Das ist mein Problem momentan 😉



  • Mir fällt grad nichts besseres ein, als:

    Tform10* form10 = new TForm10();
    if( form10 != 0 )
        //Menueintrag erstellen
    

    Edit: Vergiss das mal wieder, das kracht so oder so beim kompilieren..

    Aber geht zur Kompilezeit sicher anders, haben die Header der Forms keine Includeguards? (Oder macht Borland das per #pragma once?) Weil dann könnste per Preprocessor was machen.



  • Das Problem ist ja, wenn ich die CPP nicht einbinde, existiert auch keine Klasse TForm10, demzufolge kann ich kein new machen, da der Compiler ja garnicht die Klasse kennt.

    Ich dachte es gibt irgendeine möglichkeit ob eine "Variable" bzw in dem Fall Klasse existiert. In PHP hat man mit isset() die Möglichkeit zu prüfen, ob eine Variable existiert. Gibt es soetwas nicht für C++?



  • Nicht das ich wüsste, aber bevor ich noch mehr Blödsinn erzähle..



  • Ich kenne den CBuilder zwar nicht. Was mir aber spontan einfällt, wäre eine Art globales Flag. In irgendeiner separaten Headerdatei erstellst du sowas in der Art:

    class TForm10Flag
    {
    public:
        static TForm10Flag& instance()
        {
            static TForm10Flag instance_;
            return instance_;
        }
    private:
        bool value_;
    public:
        // um unser Flag abzufragen
        operator bool() const
        {
            return value_;
        }
        // um unser Flag zu setzen
        TForm10Flag& operator =(bool rhs)
        {
            value_ = rhs;
            return *this;
        }
    private:
        TForm10Flag()
            : value_(false)
        {
        }
    };
    
    namespace
    {
        TForm10Flag& TForm10Exists = TForm10Flag::instance();
    }
    

    Es ist praktisch eine globale Instanz, welche lediglich einen boolschen Wert als Member hat, der angibt, ob TForm10 exisitiert oder nicht. Per default wird dieser erstmal mit false initialisiert. Über TForm10Exists kann man auf die Instanz zugreifen.

    In der .cpp Datei mit TForm10 wird diese Headerdatei dann eingebunden und der boolsche Wert während der statischen Initialisierungsphase auf true gesetzt, also praktisch die Existenz von TForm10 bestätigt.

    class TForm10Confirmed
    {
    private:
        TForm10Confirmed()
        {
            TForm10Exists = true;
        }
    };
    
    namespace
    {
        TForm10Confirmed TForm10Dummy;
    }
    

    Die dummy Variable hat also keinen wirklichen Zweck, sondern soll lediglich dazu dienen, eine Funktion aufzurufen (ctor), die unsere globale Instanz ändert.

    Dort, wo du dann wissen willst, ob die TForm10 .cpp kompiliert und gelinkt wurde, kannst du einfach schreiben:

    if (TForm10Exists)
    {
        //...
    }
    

    (Natürlich nicht vergessen, die Headerdatei einzubinden.)
    Zu beachten ist, dass diese Abfrage erst nach der statischen Initialisierungsphase, also praktisch ab main(), möglich ist. Sofern man es früher braucht, müssten ein paar Sachen angepasst werden.

    Ansonsten werde ich aus deiner Beschreibung noch nicht ganz schlau. TForm10 muss doch irgendwo bekannt sein, also dort, wo die Form zur Anzeige gebracht wird. Kann man denn nicht auf dieser Basis das Menü entsprechend anpassen?

    Zum Thema PHP und isset, das gibt es in C++ nicht. C++ hat ein statisches Typsystem, dh es gibt zur Laufzeit keine Bezeichner mehr, weder Klassen, noch Variablen, noch Funktionen.



  • Groovemaster warum baust du so einen Hack? Das ist doch gar nicht nötig.

    Mausfänger, mach das einfach richtig und schreib ne Interfaceklasse von der du TForm10 (was für ein genialer Name btw.) ableitest und schreib ne Factory-Klasse dazu.



  • lolz schrieb:

    Mausfänger, mach das einfach richtig und schreib ne Interfaceklasse von der du TForm10 (was für ein genialer Name btw.) ableitest und schreib ne Factory-Klasse dazu.

    Und wie will er das machen, wenn TForm10 nicht bekannt ist? Zudem, TForm10 ist doch bestimmt irgend so eine automatisch durch den Designer erstellte Layout Klasse. Die kann er nicht einfach so ableiten. Und Factory? Ihm geht es wohl nicht um das Erstellen der Form, sondern um die Regelung des Menüs anhand des Vorhandenseins der Form.
    Vllt. wäre es ja besser, ihn ins Borland Forum zu verschieben. Evtl. wissen die, was genau er vorhat.



  • groovemaster schrieb:

    lolz schrieb:

    Mausfänger, mach das einfach richtig und schreib ne Interfaceklasse von der du TForm10 (was für ein genialer Name btw.) ableitest und schreib ne Factory-Klasse dazu.

    Und wie will er das machen, wenn TForm10 nicht bekannt ist?

    Wie will er was machen?

    Zudem, TForm10 ist doch bestimmt irgend so eine automatisch durch den Designer erstellte Layout Klasse. Die kann er nicht einfach so ableiten.

    Das kann trotzdem gehen (kenn mich mit dem Designer nicht aus).

    Und Factory? Ihm geht es wohl nicht um das Erstellen der Form, sondern um die Regelung des Menüs anhand des Vorhandenseins der Form.

    Wenn es die Klasse nicht gibt, dann könnte die Factory eine exception werfen, oder sonst signalisieren, dass es keine TForm10 gibt.

    Aber wenn ich so darüber nachdenke, sollte man vllt. einfach den Präprozessor benutzen.



  • C++ ist ne eher statische sprache ...

    Also dynamisch typen abfragen, existenz von bestimmten symbolen etc tut sich c++ schwer. das core c++ ist nun mal typsicher! Andere Sprachen koennen das, in c++ kann man sowas aehnliches auch implementieren, nur isses ned einfach und bringt nen ziemlichen performance overhaed mit.

    Wer dynamisch linkerinformationen in c++ abfragen will, hat allgemein noch leichte probleme mit dem grundlegenden Design von c++ (als Programmiersprache)

    Und Lolz hat in dem falle recht.
    der client kann nur das bedienen was er kennt. entweder kennt der client alle moeglichkeiten die in allen aktuellen und noch kommenden Biblotheken stecken ...
    oder man einigt sich bei der communication zwischen client und lib auf eine grundlegende schnittstelle, und die unterschidlichen bibs begnuegen sich nur mit einer unterschiedlichen implementierung.

    willst du richtige dynamic, also Objecte die unvorhergesehene funktionalitaet zur verfuegung stellen, musst du weiter ausholen ...
    Du brauchst dann sogenannte Dispatcher ..., das ist unter c++ naturelich auch moeglich, wobei du dort aber deine logischen dynamischen funktionsaufrufe durch einige wenige statische funktionsaufrufe emulierst.
    Wenn man tiefer mit com/corba zu tun hat, bekommt man nen gefuehl fuer was da abgeht.
    COM bringt eh nen Dispatcher mit, vielleicht solltest dich da dran halten ....

    Wobei diese Themen IMHO ned wirklich c++ einsteigerfreundlich sind....

    Ciao ....



  • Das kann trotzdem gehen (kenn mich mit dem Designer nicht aus).

    Durchaus möglich. Dafür kenne ich Borland zu wenig.

    Wenn es die Klasse nicht gibt, dann könnte die Factory eine exception werfen, oder sonst signalisieren, dass es keine TForm10 gibt.

    Das Problem ist doch das Timing. Die Factory kommt erst dann zur Ausführung, wenn die Instanz erstellt wird. Wer sagt dir denn, dass die benötigten Informationen nicht schon früher benötigt werden? Grundsätzlich bekomme ich auch Bauchschmerzen, wenn ich sehe, was er vorhat. Aber anhand der bisherigen Beschreibungen war der "Hack" von mir einfach eine billige Lösung, das zu erreichen.



  • Naja, gibt es nicht eine Liste der Basisobjecte -> Form über die man laufen kann ? Da man ohnehin nicht den genauen Typ kennt, kann man eh nur den kleinsten gemeinsamen Nenner nutzen.

    Ob es solche Listen gibt, muss man entsprechend in der Doku des Compilers/Frameworks nachsehen.


Anmelden zum Antworten