VCL und dynamic_cast



  • Kannst du den BCB2007 mit dem 2009er stabilitätsmäßig vergleichen? Ich konnte mich bis jetzt noch nicht dazu durchringen den neuen zu erwerben.
    Unicode spielt für mich keine Rolle und die neuen C++Features werde ich aus Kompatibilitätsgründen so schnell nicht einsetzen. Deswegen habe ich jetzt noch keinen Bedarf für ein Update gesehen.



  • Hi Braunstein,
    die 2007er Version besitze ich nicht, deshalb kann ich dir leider keinen "Vergleich anbieten". 😉



  • Aber die Aussage, das mit dem CB keine professionelle SW erstellt werden kann, ist schlichtweg falsch.

    Das habe ich ja auch nie behauptet. Ich bin schon der Meinung, dass man mit dem BCB 6 professionelle Software erstellen kann (schliesslich tut unsere Firma genau das). Ich bin allerdings der Meinung, dass das Produkt BCB 6.0 kein professionelles Werkzeug ist, und zwar aus den Gründen, die ich früher schon angeführt habe.



  • Auch hier hat sich die Situation verändert, und zwar bereits in XE. Delphi-Klassen können nach wie vor Interfaces handhaben, allerdings nur solche, die auch von Delphi als Interfaces anerkannt werden - also solche, die von IUnknown / IInterface ableiten. Läßt man das außer acht, so bekommt man eine Warnung:

    class IMyIntf
    {
        virtual void foo (void) = 0;
    };
    
        // Warnung W8130: Interface 'IMyIntf' ist nicht von IUnknown abgeleitet. (Interfaces müssen von IUnknown abgeleitet sein)
    class TInterfacedSomething : public TObject, public IMyIntf
    {
    };
    

    Außerdem gibt es seit C++Builder XE eine neue Klasse TCppInterfacedObject<> , die einem das erneute Implementieren von QueryInterface() , AddRef() und Release() erspart:

    // die IID ist nach wie vor optional
    class __declspec (uuid ("{3B6D49E8-712C-4442-9A02-1E37F107516F}")) IMyInterface : public IUnknown
    {
    public:
        void foo (void) = 0;
    };
      // DelphiInterface<> ist ein Smart-Pointer für Delphi-/COM-Interfaces und dient dem Komfort.
      // Das Präfizieren des Typedefs mit "_di_" ist Konvention und wird auch vom .hpp-Generator des Delphi-Compilers so gemacht.
    typedef DelphiInterface<IMyInterface> _di_IInterface;
    
    class TMyObject : public TInterfacedObject, public IMyInterface
    {
    public:
        ULONG   __stdcall AddRef (void)
        { return TInterfacedObject::_AddRef (); }
        ULONG   __stdcall Release (void)
        { return TInterfacedObject::_Release (); }
        HRESULT __stdcall QueryInterface (REFIID iid, void** p)
        { return TInterfacedObject::QueryInterface (iid, p); } 
    
        void foo (void) { ... }
    };
    

    wird also zu

    class TMyObject : public TCppInterfacedObject<IMyInterface>
    {
    public:
        void foo (void) { ... }
    };
    

    (Möglich wird das durch das Beheben des in QC #66382 beschriebenen Problems.)

    Es ist weiterhin nicht möglich, dynamic_cast<>() mit Interfaces zu benutzen. Die technischen Gründe dafür stehen hier; seit XE gibt es aber als Ersatz dafür den interface_cast<>() , mit dem man nach Belieben zwischen Interfaces und Klassen hin- und hercasten kann:

    TMyObject* obj = new TMyObject;
    
            // implicit upcast to guard interface
        _di_IMyInterface myInterface = obj;
    
            // explicit object->interface upcast
        _di_IInterface i2 = interface_cast<IInterface> (obj);
    
            // explicit interface->interface downcast
        _di_IMyInterface i3 = interface_cast<IMyInterface> (i2);
    
            // explicit interface->object downcast
        TMyObject* obj2 = interface_cast<TMyObject> (i3);
    

    Daß man zu einem bestimmten Interface hin-casten kann, erfordert natürlich, daß diesem Interface mittels __declspec(uuid()) eine IID zugeordnet ist.

    Wohlgemerkt ist interface_cast<>() keine Keyword-Erweiterung, sondern ein Funktionstemplate im System-Namespace. Allerdings verweist der Compiler auf interface_cast<> , wenn man versehentlich dynamic_cast<>() verwendet:

    // Warnung W8131: Umwandlung des Interface 'IUnknown' in eine Klasse im Delphi-Stil. Verwenden Sie
            // stattdessen 'System::interface_cast<TBar>(intf)'
        TMyObject* obj3 = dynamic_cast<TMyObject*> (i3);
    


  • Danke für die nützlichen Infos.

    Zu Zeiten der in diesem Thread erwähnten BCB5 und 6, gab es so nützliche Bücher wie den C++ Builder Developers Guide. Da konnte man sowas schön nachlesen.

    Wir können dich vermutlich nicht überreden, einen Nachfolger zu verfassen ? 😕 🙂



  • nn schrieb:

    Zu Zeiten der in diesem Thread erwähnten BCB5 und 6, gab es so nützliche Bücher wie den C++ Builder Developers Guide. Da konnte man sowas schön nachlesen.

    Ich weiß, daß bei Embarcadero wieder an einem "C++Builder Developers Guide" gearbeitet wird (wobei fraglich ist, ob es das nochmal in Druckform geben wird). Das Buch bestand ja im Wesentlichen aus den in schön lesbare Form gebrachten Inhalten der Online-Hilfe. Die aktuelle Online-Hilfe beinhaltet wieder die meiste Dokumentation, die zwischenzeitlich mal verlorengegangen ist, und auch neuere Themen werden oft gut behandelt. Aber bis es wieder den schlüssigen Zusammenhang des "Developers Guide" hat, muß noch einiges getan werden.

    nn schrieb:

    Wir können dich vermutlich nicht überreden, einen Nachfolger zu verfassen ? 😕 🙂

    Haha 😉 Nein; ich habe weder einen Job bei Embarcadero noch überflüssige Lebenszeit. Ich könnte aber solche Informationen on-demand (wenn es z.B. hier im Forum angefragt wird) auf meiner Webseite in einem Artikel zusammenzustellen.



  • audacia schrieb:

    Sich darüber zu beschweren, daß ein mittlerweile gute acht Jahre altes Produkt nicht mehr zeitgemäß ist, halte ich, offen gesagt, für albern.

    Ich schon. Denn die Features sind ja "drin", sollten also funktionieren. Das taten sie halt schon vor 8 Jahren nicht. Das sie es mittlerweile in späteren Versionen tun ist keine Entschuldigung für das ursprüngliche Produkt.



  • Morle schrieb:

    Das sie es mittlerweile in späteren Versionen tun ist keine Entschuldigung für das ursprüngliche Produkt.

    Stimmt.

    Ich denke, ich muß die zitierte Aussage einschränken. Ich war mir nicht darüber im klaren, wie schwer es sein kann, ein Lock-in auf eine ältere Version zu überwinden.

    Andererseits wirst du zustimmen, daß es albern wäre, sich über die von Windows 98 verursachten Alltagsbeschwerden zu beklagen, solange man genausogut auf ein modernes Windows migrieren könnte. Darauf wollte ich hinaus.



  • audacia schrieb:

    Andererseits wirst du zustimmen, daß es albern wäre, sich über die von Windows 98 verursachten Alltagsbeschwerden zu beklagen, solange man genausogut auf ein modernes Windows migrieren könnte. Darauf wollte ich hinaus.

    Nur das man eben nicht "einfach so" migieren kann. Wir entwickeln mittlerweile mit was anderem. Für unsere Abteilung z.B. wären das mal eben 20 Lizenzen für eine aktuelle Version vom Builder zusätzlich zu unserer eigentlichen IDE. Und das nur um alte Applikationen weiter zu pflegen und sich damit ggf. auch noch Probleme beim Update einzuhandeln? Welcher Chef lässt sich denn auf sowas ein?
    Ich hatte mit Dir doch schonmal darüber geredet, glaube ich.



  • Morle schrieb:

    Und das nur um alte Applikationen weiter zu pflegen und sich damit ggf. auch noch Probleme beim Update einzuhandeln? Welcher Chef lässt sich denn auf sowas ein?

    Hängt natürlich stark von der Zukunftsplanung bezüglich dieser alten Anwendungen ab, nicht?

    Morle schrieb:

    Ich hatte mit Dir doch schonmal darüber geredet, glaube ich.

    Ja, wir hatten die Diskussion schon.


Anmelden zum Antworten