Seltsames Verhalten einer selbst geschriebenen Klasse - Automatischer Destruktoraufruf

  • C++

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    Trade schrieb:

    Managed C++ ist
    einzig und allein dafür gut, einen managed Wrapper um eine native DLL zu schreiben, die gemeinsam in einer DLL gepackt sind.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    guck, nach viel mühsal konnte ich die liste umstellen auf vector, und hat imo den Code ziemlich vereinfacht:
    vorher

    C-Quellcode

    1. class Anwendung : public Fenster{
    2. private:
    3. int anzahl;
    4. Komponente* liste[1000];
    5. public:
    6. Anwendung();
    7. bool liesDatei(std::string fName);
    8. virtual void reagiere(unsigned int art, int xm, int ym, int taste, HDC dc);
    9. void zeichneAlles(HDC dc);
    10. }; //class Anwendung
    11. // ====================================
    12. #include "anwendung.h"
    13. Anwendung::Anwendung(){
    14. anzahl = 0;
    15. }
    16. bool Anwendung::liesDatei(std::string fName){
    17. std::ifstream fin;
    18. int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; std::string text = ""; std::string klasse = "";
    19. fin.open(fName.c_str());
    20. if (!fin.good()){
    21. return 1;
    22. }
    23. while (true){
    24. fin >> klasse;
    25. if (!fin.good()){
    26. break;
    27. }
    28. if (klasse == "Linie"){
    29. fin >> x1 >> y1 >> x2 >> y2;
    30. liste[anzahl] = new Linie(x1, y1, x2, y2);
    31. anzahl++;
    32. }
    33. if (klasse == "Kreis"){
    34. fin >> x1 >> y1 >> x2 >> y2;
    35. liste[anzahl] = new Kreis(x1, y1, x2, y2);
    36. anzahl++;
    37. }
    38. if (klasse == "Text"){
    39. fin >> x1 >> y1;
    40. getline(fin, text);
    41. liste[anzahl] = new Text(text, x1, y1);
    42. anzahl++;
    43. }
    44. if (klasse == "Button"){
    45. fin >> x1 >> y1 >> x2 >> y2;
    46. getline(fin, text);
    47. liste[anzahl] = new Button(x1, y1, x2, y2, text);
    48. anzahl++;
    49. }
    50. }
    51. return true;
    52. }
    53. void Anwendung::reagiere(unsigned int art, int xm, int ym, int taste, HDC dc){
    54. std::cout << "art=" << art << "; xm=" << xm << "; ym=" << ym << "; taste=" << taste << "; dc=" << dc << std::endl;
    55. zeichneAlles(dc);
    56. for (int i = 0; i < anzahl; i++){
    57. switch (art)
    58. {
    59. case 512: //Maus bewegt
    60. liste[i]->MausBewegt(xm, ym);
    61. break;
    62. case 513: //Maus geklickt
    63. liste[i]->MausLinksGedrueckt(xm, ym, dc);
    64. break;
    65. case 514: //Maus loslassen
    66. liste[i]->MausLinksLoslassen();
    67. break;
    68. default:
    69. break;
    70. }
    71. }
    72. zeichneAlles(dc);
    73. }
    74. void Anwendung::zeichneAlles(HDC dc){
    75. HDC mdc = gibSpeicherDC();
    76. for (int i = 0; i < anzahl; i++){
    77. liste[i]->zeichnen(mdc);
    78. }
    79. kopiereBitmap(mdc, dc);
    80. loesche(mdc);
    81. }
    nachher

    C-Quellcode

    1. class Anwendung : public Fenster{
    2. private:
    3. std::vector<Komponente*> components;
    4. public:
    5. bool liesDatei(std::string fName);
    6. virtual void reagiere(unsigned int art, int xm, int ym, int taste, HDC dc);
    7. }; //class Anwendung
    8. // ====================================
    9. #include "anwendung.h"
    10. bool Anwendung::liesDatei(std::string fName) {
    11. std::ifstream fin;
    12. int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; std::string text = ""; std::string klasse = "";
    13. fin.open(fName.c_str());
    14. while (true) {
    15. Komponente *cmp;
    16. fin >> klasse;
    17. if (!fin.good()) return 1;
    18. if (klasse == "Linie") {
    19. fin >> x1 >> y1 >> x2 >> y2;
    20. cmp = new Linie(x1, y1, x2, y2);
    21. }
    22. else if (klasse == "Kreis") {
    23. fin >> x1 >> y1 >> x2 >> y2;
    24. cmp = new Kreis(x1, y1, x2, y2);
    25. }
    26. else if (klasse == "Text") {
    27. fin >> x1 >> y1;
    28. getline(fin, text);
    29. cmp = new Text(text, x1, y1);
    30. }
    31. else if (klasse == "Button") {
    32. fin >> x1 >> y1 >> x2 >> y2;
    33. getline(fin, text);
    34. cmp = new Button(x1, y1, x2, y2, text);
    35. }
    36. else continue;
    37. components.push_back(cmp);
    38. }
    39. }
    40. void Anwendung::reagiere(unsigned int art, int xm, int ym, int taste, HDC dc) {
    41. std::cout << "art=" << art << "; xm=" << xm << "; ym=" << ym << "; taste=" << taste << "; dc=" << dc << std::endl;
    42. for (Komponente*cmp : components) {
    43. switch (art) {
    44. case 512: //Maus bewegt
    45. cmp->MausBewegt(xm, ym);
    46. break;
    47. case 513: //Maus geklickt
    48. cmp->MausLinksGedrueckt(xm, ym, dc);
    49. break;
    50. case 514: //Maus loslassen
    51. cmp->MausLinksLoslassen();
    52. break;
    53. default:
    54. break;
    55. }
    56. }
    57. for (Komponente*cmp : components)cmp->zeichnen(dc);
    58. }
    Auch das Zeichnen war komisch, zum einen wurde immer 2 mal gezeichnet, und die zeichnen-Methode hat auch iwas rumkopiert - wozu, verstund ich nicht, und weg damit :evil:

    Wenn ich länger hingucke, kriege ich den Eindruck, man könnte der Komponente-Klasse auch einen virtuellen Konstruktor spendieren, der son ifStream-Dingens nimmt, und mit dem eine Komponente dann ihre Werte selbst aus dem Stream liest.
    Ich würde das ehrlich gesagt alles weglegen und neu machen. Da sind ziemlich grobe Fehler drin. Dann hätte man auch die Möglichkeit mal Englisch zu Programmieren und so Sachen wie Speicher freizugeben ;)
    Du könntest dir auch spaßeshalber mal GCL angucken (s. Signatur) die Klassen window und graphics, da kann man ganz bequem und angenehm rendern mit Transformationen und allem drum und dran.
    Jo, es fehlt immer noch delete/delete[], mal von der Namensnennung abgesehen. Oder wie schon gesagt sollte zumindest ein unique_ptr<T> verwendet werden. Normale Klassen etc. landen auf dem Stack und werden da selbstständig gelöscht, Pointer kommen aber auf den Heap und da muss man sie selber löschen, sonst bleiben Memory Leaks.
    Wenn ich mich recht entsinne, wollte das Radinator jedoch ja noch ändern.

    Und ansonsten, jo, GCL (ebenfalls s. Signatur :P).

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: