Operator new[] für abgeleitete Klassen
-
@john-0 Sorry, DocShoe hatte recht. Alles wie von Anfang an falsch.
Ich lern mal RAII: Weiß jemand ob C++Builder 2009 schon mit C++11 compiliert? Ansonsten kann ich mir das sparen.
-
Ne, der C++ Builder 2009 kann kein C++11, und auch mit templates hat der so seine Probleme. Ist halt noch der alte, verbuggte bcc32 Compiler. Aber RAII funktioniert auch ohne C++11, das ist ein Konzept, und kein Sprachfeature.
Ohne C++11 hast du leider keine vernünftigen smart_ptr. Ich habe damals für das RAD Studio 2007 die boost Bibliotheken selbst übersetzt, das war nicht trivial, und nur für boost::shared_ptr würde ich das nicht versuchen.
Aber als Programmieraufgabe kannst du dir ja die Implementierung einer eigenen shared_ptr Klasse setzen, wenn man so Sachen wie thread safety, weak_ptr und custom deleter weglässt ist das nicht so schwierig und mit 50-100 Zeilen Code zu machen.
-
Danke an alle für die Ratschläge.
Ich glaube nun ist an der Zeit meinen alten launenhaften C++Builder zu verschrotten. Weil der neue auch nichts taugt, wende ich mich nun Linux und Phyton zu. Hier gibts noch Aufbruchslaune. Obwohl ich schon 1980 mit einem UNIX-Mainframe und 1990 mit Unix-Sun-Sparc rummachte, konnte ich mich noch nicht für Linux entscheiden. Damals war Windows soweit wie Linux erst vor ~5 Jahren. Jetzt erscheint mir das Ende der Fahnenstange erreicht und fang nochmal an.
Glück auf, und sonstige Grüße.
Rudi
-
@RudiMBM sagte in Operator new[] für abgeleitete Klassen:
Weil der neue auch nichts taugt, wende ich mich nun Linux und Phyton zu.
Python ist aber leider nicht für seine Schnelligkeit bekannt. Denkbar das du zu deinem Problem ein Performanceproblem bekommt.
Warum nutzt du nicht einen neuere Compiler ala GCC der von Compiler von Visual Studio?
-
Bevor ihr über potentielle Geschwindigkeitsprobleme sinniert: ich verstehe nicht, warum @RudiMBM nicht einfach erstmal einen
vector<BaseClass*>
nimmt. Meinetwegen auch mit owning raw ptr, wenn der Compiler kein C++11 kann. Das wird in >99% der Fälle schon nicht zu langsam sein.
-
@DocShoe sagte in Operator new[] für abgeleitete Klassen:
Ohne C++11 hast du leider keine vernünftigen smart_ptr. Ich habe damals für das RAD Studio 2007 die boost Bibliotheken selbst übersetzt, das war nicht trivial, und nur für boost::shared_ptr würde ich das nicht versuchen.
Unter UNIX ging das ganze sehr gut mit C++98 Compiler (GCC und MIPSPro). Für einen shared_ptr braucht es kein C++11, für unqiue_ptr ist C++11 oder neuer hingegen Pflicht.
@RudiMBM sagte in Operator new[] für abgeleitete Klassen:
Danke an alle für die Ratschläge.
Ich glaube nun ist an der Zeit meinen alten launenhaften C++Builder zu verschrotten. Weil der neue auch nichts taugt, wende ich mich nun Linux und Phyton zu. Hier gibts noch Aufbruchslaune. Obwohl ich schon 1980 mit einem UNIX-Mainframe und 1990 mit Unix-Sun-Sparc rummachte, konnte ich mich noch nicht für Linux entscheiden.UNIX lief traditionell nicht auf Mainframes sondern auf Minicomputern. Mittlerweile kann man auf IBMs zSeries z/Linux betreiben, aber nicht IBMs eigenes UNIX AIX. Das läuft nur auf der Power Hardware, die die konsolidierte gemeinsame Plattform für IBMs UNIX AIX und dem Nachfolger des Mini Computer OS der AS/400 sind, und natürlich läuft darauf auch Linux für Power. IMHO ist BS2000 die einzige nicht IBM Mainframe Plattform, die bis heute überlebt hat.
Unter Linux gibt es ein Sammelsurium von freien bzw. frei verfügbaren C und C++ Compilern: GCC, clang, Intel, nVidia (vormals PGI), AMD, … Bei Deinen Problembeschreibungen erscheint mir NumPy eine sinnvoller Einstieg zu sein, wenn Du denn wechseln willst. Mein Rat wäre zuerst einen freien neueren C++ Compiler unter Windows zu probieren. Ein Wechsel zieht so einiges nach sich, so dass es da nicht nur ums Programmieren geht.
-
Jups, deswegen schrub ich auch
shared_ptr
. Ohne Move-Semantik keinunique_ptr
. Und es gibt zwei große Probleme, wenn man mit dem RAD Studio/Builder arbeitet:- der bcc32 C++ Compiler, der nicht mal zu sich selbst kompatibel ist. Ok, das ist übertrieben, aber die ganze Toolchain hat schon ordentliche Macken.
- die Visual Component Framework (VCL). Grafische Komponenten in Delphi, die sich mit dem C++ Builder nutzen lassen. Wird von keinem anderen C++ Compiler unterstützt. D.h., wenn man sich vom C++ Builder trennt, dann trennt man sich auch von seinem GUI. Andererseits ist der bcc32 Compiler auch so schlecht, dass sich Open Source Frameworks nicht damit übersetzen lassen.
-
Hallo, hier noch einen Nachtrag.....
Meine Idee war einen ClassPointer zu haben, mit dem ich in der gesamten Anwendung zugriff auf die ausgewählte Subklasse C_RechenXX habe.
Das kann natürlich nur ein Ptr auf die Basisklasse sein. Soweit funktioniert das.
Damit aber handele ich mir die Nachteile ein:- Kein direkter Zugriff auf public Eigenschaften der Subklassen.
- Alle public Subklassen-Methoden müßen abgeleitete sein.
- Zeigerarithmetik des Pointers bezieht sich immer auf die Size der Basisklasse. Sowas geht schwer in die Hose und war auch mein ursprüngliches Problem.
Warum kann ich das trotzdem anwenden?:
- Meine Subklassen haben keine public Eigenschaften
- Ist eh so.
- Die Zeigerarithmetik mußte ich mir selber basteln, war aber erstaunlich leicht.
Also, das Programm läuft, auch wenn es so nicht "State of the Art" ist
Nun sieht es so aus.:
class C_Rechnen { public: C_Rechnen() ; ~C_Rechnen(); virtual void NeueAuswertung() = 0; virtual void Erstellen(int) = 0; virtual C_Rechnen* Next() = 0; virtual C_Rechnen* ArrPos( int ) = 0; long double innermax, innermin, outermax, outermin; long int ax, ay; int itercount; }; C_Rechnen::~C_Rechnen() {} class C_RechnenMB : public C_Rechnen { public: C_RechnenMB(); ~C_RechnenMB() {}; C_Rechnen* Next() { __int8 *aa = (__int8*)this; aa += sizeof(C_RechnenMB); return (C_Rechen*)aa; } C_Rechnen* ArrPos( int ix) { __int8 *aa = (__int8*)this; aa += sizeof(C_RechnenMB) * ix; return (C_Rechen*)aa; } void NeueAuswertung() {}; void Erstellen(int) {}; }; class C_RechnenBB : public C_Rechnen { public: C_RechnenBB(); ~C_RechnenBB() {}; C_Rechnen* Next() { __int8 *aa = (__int8*)this; aa += sizeof(C_RechnenBB); return (C_Rechen*)aa; } C_Rechnen* ArrPos( int ix) { __int8 *aa = (__int8*)this; aa += sizeof(C_RechnenBB) * ix; return (C_Rechen*)aa; } void NeueAuswertung() {}; void Erstellen(int) {}; int BBdaten; // Kein zugriff mit BasisPtr, wird aber bei sizeof(C_RechnenBB) mitgezählt. }; int main () { int Mode = 1; size_t Anzahl = 10; C_Rechnen *ErgAnzArray, *ErgAnz; switch (Mode) { case 1: ErgAnzArray = new C_RechnenMB[Anzahl]; break; case 2: ErgAnzArray = new C_RechnenBB[Anzahl]; break; default ErgAnzArray = new C_RechnenXX[Anzahl]; break; } } ErgAnz = ErgAnzArray; for ( ................) { ErgAnz->ax = 656565; ErgAnz->Erstellen(); ErgAnz = ErgAnz->Next(); } ........ ErgAnz = ErgAnzArray->ArrPos( nth-Element ); // entspricht ErgAnz[ nth-Element ]
Ist ne' Hauruck-Methode, aber läuft!
Gruß Rudi
-
Sowas hab ich doch vor Tagen schon gepostet, nur in typsicher:
class C_Rechnen { virtual C_Rechnen* advance( C_Rechnen* current ) const = 0; }; class C_RechnenMB { C_Rechnen* advance( C_Rechnen* current ) const override { // Pointer wird um die Größe der konkreten Klasse verschoben C_RechnenMB* tmp = dynamic_cast<C_RechnenMB*>( current ); return tmp ? ++tmp : nullptr; } } // Pointer auf nächstes Element wird durch das Element selbst bestimmt. C_Rechnen* arr = new C_RechnenMB[2]; arr = arr->advance( arr );
-
@DocShoe pow! bis du schnell.
-
Zwei Monitore und ein großes Projekt zu übersetzen
-
@DocShoe Drei Monitore, und ich spiel blos rum.
-
Aber jetzt reichts auch bis Montag. Schönes Wochenende!