Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Brauche Hilfe: New / malloc bei Klassen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
13.04.2016, 17:06 Uhr
manug



Hallo, ich bin noch Anfänger und habe folgendes Problem:

Habe eine Klasse Punkt und eine Klasse Pfad. Der Punkt-Konstruktor hat 2 Parameter, int x und int y (für Koordinaten).
In der Klasse Pfad möchte ich im Konstruktor nun Speicher freihalten für ein Array das Punkte nacheinander ablegt.
Wie funktioniert das mit dem new Operator? Mit malloc funktioniert es bereits.

Hier der Quellcode:

C++:
// teil der cpp der Klasse Punkt

Punkt::Punkt(int x, int y)
{
    _x = x;
    _y = y;
}

// teil der h der Klasse Pfad

class Pfad
{
    Punkt* pPunkte;
    int iAnzPunkte; //Anzahl der Punkte bzw Länge des Pfades
    int iZaehler; //aktuelle Position auf dem Pfad
}
//teil der cpp der Klasse Pfad

Pfad::Pfad(int anzPunkte)
{
    iZaehler = 0;
    iAnzPunkte = anzPunkte;
    //pPunkte = new Punkt[anzPunkte];                -> funktioniert nicht
    //pPunkte = (Punkt*)malloc(anzPunkte*sizeof(Punkt));   -> funktioniert
}







Fehlermeldung: Für die Klasse Punkt ist kein Standartkonstruktor verfügbar

Danke im vorraus!

Dieser Post wurde am 14.04.2016 um 10:30 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.04.2016, 09:43 Uhr
ao

(Operator)


Nein, es funktioniert nicht mit malloc. malloc legt zwar den Speicher an, aber es initialisiert die Objekte nicht, weil die Konstruktoren nicht aufgerufen werden. Die Punkte haben irgendwelche zufälligen Koordinaten.

Und mit new funktioniert es nicht, weil Punkt keinen parameterlosen Konstruktor hat (wie die Fehlermeldung schon sagt). Was da Ärger macht, ist die Mischung aus C++ (Objekte mit parametrisiertem Konstruktor) und C (Array-Verwaltung über Pointer).

Wenn du in ordentlichem C++ eine Ansammlung von Punkten definieren und verwalten willst, dann verwende std::vector<Punkt> (oder eine andere geeignete Containerklasse, z.B. std::list) und gib der Klasse Punkt einen Copy-Konstruktor und einen operator=. Die braucht der Container, um die Objekte zu speichern und wieder herauszugeben.

Dieser Post wurde am 14.04.2016 um 09:47 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.04.2016, 12:23 Uhr
manug



Okay danke, aber der Konstrukor von Punkt wird in der main() aufgerufen. Dort kann ich in den Pfad der Reihe nach Koordinaten einfügen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
14.04.2016, 13:29 Uhr
ao

(Operator)



Zitat von manug:
Okay danke, aber der Konstrukor von Punkt wird in der main() aufgerufen. Dort kann ich in den Pfad der Reihe nach Koordinaten einfügen.

Zeig bitte den Code, der das macht.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
14.04.2016, 15:33 Uhr
manug




C++:
class Punkt
{
    int _x; // X-Koordinate
    int _y; // Y_Koordinate
public:
    Punkt(int x, int y);
    ~Punkt();
    void print();
};

-----------------------------------------------------------

#include "Punkt.h"
#include <iostream>
using namespace std;


Punkt::Punkt(int x, int y)
{
    _x = x;
    _y = y;
}


Punkt::~Punkt()
{
}


void Punkt::print()
{
    cout << '(' << _x << ',' << _y << ')';
}

----------------------------------------------------------------

#pragma once
#include "Punkt.h"

class Pfad
{
    Punkt* pPunkte; // Pointer auf Punkte des Pfads
    int iAnzPunkte; //Anzahl der Punkte bzw Länge des Pfades
    int iZaehler; //aktuelle Position auf dem Pfad
public:
    Pfad(int anzPunkte);
    ~Pfad();
    void insertKoord(Punkt& p);
    void printKoord(int i);
    int get_aktuellePosition();
};

-------------------------------------------------------------------

#include "Pfad.h"
#include "stdlib.h"
#include <iostream>
using namespace std;

Pfad::Pfad(int anzPunkte)
{
    iZaehler = 0;
    iAnzPunkte = anzPunkte;
    //pPunkte = new Punkt[anzPunkte];                //betroffene Stelle
    pPunkte = (Punkt*)malloc(anzPunkte*sizeof(Punkt));
}


Pfad::~Pfad()
{
    free(pPunkte);        //gebe Speicher wieder frei
    pPunkte = 0;        //setze Zeiger zurück
}

void Pfad::insertKoord(Punkt& p)        
{
    if (iZaehler < iAnzPunkte) //nur wenn noch Platz auf dem Pfad
    {
        pPunkte[iZaehler] = p;
        iZaehler++;
    }
}

void Pfad::printKoord(int i)
{
    if (i < iZaehler) //gebe nur alle vorhandenen Punkte aus
    {
        pPunkte[i].print();
    }
}

int Pfad::get_aktuellePosition()
{
    return iZaehler;
}


-----------------------------------------------------------------------------------
//main
#include <iostream>
using namespace std;
#include "Pfad.h"

int main()
{
    int anzpunkte = 0;
    bool b = true;
    cout << "Wie lang soll der Pfad sein?" << endl;
    cin >> anzpunkte;

    Pfad derPfad(anzpunkte);
    Punkt einPunkt(0, 0);

    while (b == true)
    {
        char c;
        int x, y;
        cout << "\n\nPunkt einfuegen[e], Punkte ausgeben[z] oder Programm beenden[x]? -->";
        cin >> c;

        switch (c)
        {
        case 'e':
            if (derPfad.get_aktuellePosition() < anzpunkte)
            {
                cout << "\nKoordinaten des Punktes:\nx: ";
                cin >> x;
                cout << "y: ";
                cin >> y;
                einPunkt = Punkt(x, y);            //Kann man das so machen?
                derPfad.insertKoord(einPunkt);
            }
            else
                cout << "Der Pfad ist voll" << endl;
            
            break;

        case 'z':
            cout << "\nGebe alle Punkte aus: ";
            for (int i = 0; i < anzpunkte; i++)
                derPfad.printKoord(i);
            break;

        case 'x':
            cout << "\nDas Programm wird beendet..." << endl;
            b = false;
            break;

        default:
            cout << "Falsche Eingabe" << endl;
        }
    }
    getchar();
    getchar();
    return 0;
}



Dieser Post wurde am 14.04.2016 um 21:25 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
18.04.2016, 16:35 Uhr
ao

(Operator)


Das funktioniert in diesem Fall, weil Punkt eine sehr primitive Klasse ist, die keine objektorientierten Elemente hat (Ableitung, virtuelle Methoden). Ein Punkt-Objekt besteht nur aus dem Speicher für die beiden Membervariablen und kann wie ein C-Struct per Zuweisung kopiert werden. Abgesehen von ein bisschen Syntax (Konstruktor und Destruktor, insertKoord-Methode mit Referenzparameter, Ausgabe über C++-Streams) könnte man das auch ganz ohne C++ als C-Programm formulieren.

Bei Klassen, die von anderen Klassen abgeleitet sind, ist dieses Konstruieren per Kopieren nicht so einfach möglich, da muss im Speicher noch einiges gemacht werden, was man besser dem Compiler überlässt. Das hat mit der sogenannten VTable zu tun, einer Tabelle von Funktionspointern, die jeder Compiler (g++, Microsoft-C++, Borland-C++, ...) auf seine eigene Weise verwalten darf. Da fummelt man besser nicht drin herum.

Das Beispiel ist ein bisschen zu einfach, um die Stärken von OO zu demonstrieren, hier überwiegt noch der Overhead (Copy-Konstruktor, =-Operator, wozu soll ich das alles machen?). Aber wenn du lernen und ausprobieren willst, dann definier mal Pfad nicht mit einem Punkt*, sondern mit einem std::vector<Punkt> und pass alles andere daran an. insertKoord macht dann nur noch push_back, und malloc und free brauchst du gar nicht mehr, und new und delete auch nicht.

Die Punkt-Klasse selber muss bestimmte Anforderungen erfüllen (Copy-Konstruktor, operator=, siehe oben), die du erst mal bereitstellen musst, damit du Punkte in einem vector verwalten kannst. Die Anwender-Klassen, die mit dem vector und seinem Inhalt umgehen (Pfad und weitere) werden dafür um einiges einfacher. Und es funktioniert auch dann noch, wenn nicht mehr Punkte verarbeitet werden, sondern erheblich komplexere Objekte.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: