Problem mit Konstruktor

Ozzy Ozborn

Erfahrenes Mitglied
Hi,

ich muss ein C++ Programm schreiben, welches sich mit Automaten befasst. Dafür hatte ich eigentlich folgenden Kontruktor gedacht:
Code:
Automat::Automat() {                                                  
    int k, m, n;
    int Qa[m];
    int Delta[n][3];
};
doch wie schaffe ich es jetzt aus meiner Main-Methode mehrere Automaten anzulegen, und auf die einzelnen zuzugreifen (ich weiß vorher nicht, wieviele es werden.)? Ich schaffe es momentan noch nicht einmal, einen einzigen anzulegen.
Automat *automat = new Automat();
aus der main führt nur zum Programmabsturz...

Muss in der Automat.h eigentlich noch mehr stehen, als:
, also noch die Eigenschaften der Automat.cpp? (Also k,m,n; wie müsste das dann aussehen?)
 
Ich gehe mal davon aus, die Zeile "Automat();" im Header Bestandteil einer richtigen Klassendeklaration ist?

Wenn du die im Konstruktur verwendeten Variablen noch in anderen Methoden verwenden willst, solltest du sie als Member der Klasse deklarieren.

Im Konstruktor verwendest du für die Deklaration von "Qa" und "Delta" die nicht initialisierten Veriablen "m" und "n" Möglicherweise ist das die Ursache für den Programmabsturz. Eigentlich sollte sich der Compiler beschweren, weil nicht konstante Werte für die Deklaration verwendet werden (macht jedenfalls der VC++ Compiler so).

Wenn du eine vorher nicht bekannte Anzahl von Instanzen deiner Automatenklasse verwalten willst, bietet sich die Verwendung einer dynamischen Datenstruktur an, die die einzelnen Objekte aufnimmt. Da du C++ programmierst, könntest du dafür z.B. die Klasse "vector" aus der STL nehmen.

Gruß
MCoder
 
Hi,

bringt es sonst etwas, dem Konstruktor das m und n zu übergeben?
Also das Automat steht in einer Klasse in der Header-Datei.
Kannst Du mir aber vielleicht noch einmal kurz sagen, wie das mit diesem "vector" gehen soll?`

MfG, Ozzy
 
bringt es sonst etwas, dem Konstruktor das m und n zu übergeben?
Parameter bringen in dem Fall nichts. Du müsstest sowas machen:
C++:
const int m = 10; // konstanten Wert bzw. Ausdruck zuweisen
const int n = 10; // konstanten Wert bzw. Ausdruck zuweisen
                                                      
int Qa[m];
int Delta[n][3];
Kannst Du mir aber vielleicht noch einmal kurz sagen, wie das mit diesem "vector" gehen soll?`
MfG, Ozzy
Dazu ein kleines Beispiel:
C++:
#include <vector>

// Elemente anlegen

std::vector<Automat> automaten;

for( int i = 0; i < 10; i++ )
{
    automaten.push_back(Automat());
}

// Zugriff auf einzelne Elemente

Automat a = automaten[1];
Automat b = automaten[2];
Automat c = automaten[3];
Automat d = automaten[4]; // usw.

// Iteration

std::vector<Automat>::iterator it;

for( it = automaten.begin(); it < automaten.end(); it++ )
{
    Automat e = *it;
}
Gruß
MCoder
 
Hallo,

du kannst die Werte im Konstruktor schon mit übergeben. Das sähe dann wie folgt aus
Code:
Automat::Automat(const int m, const int n)
{
  
 // Member sollten KLassenmember sein sonst nützen sie dir nichts-> also nicht wie hier
  int *pValue = new int[m];
  int **pDelta = new int*[n];

  pDelta[0] = new int[3];
  // die Werte musst du in einem deiner Klassenmeber halten nicht wie hier local
  int iValueMaxCount = m;
  int iDeltaMaxCount = n;

}

und nicht vergessen die Pointer im Destruktor wieder deleten.

Grüße
R.
 
Hi,

also das mit den "int *pValue = new int[m];" habe ich nicht so ganz verstanden. Hier noch mal meine 3 Dateien, bitte helft mir weiter, bin voll am Verzweifeln:

Main.cpp:
Code:
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include "Automat.h"

using namespace std;

int main(int argc, char *argv[])
{   
    char buffy[100];
    cin.get (buffy,80);
    
    int  k=0, m=0, n=0;
    sscanf(buffy," %d %d %d ", &k, &m, &n);

    Automat *automat = new Automat(k,m,n);
    
    automat->insertQa(automat, 1, 0);
    system("PAUSE");
    return EXIT_SUCCESS;
}

Automat.h:
Code:
#ifndef _AUTOMAT_H
#define _AUTOMAT_H

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Automat 
{    
public:
             Automat(const int k1, const int m1, const int n1);

             void Automat::insertQa(Automat *automat, int QaZeile, int Qa);
/*
private:  int k,m,n;
            int Qa[m];
            int Delta[n][2];
*/
};

#endif

Automat.cpp:
Code:
#include <iostream>
#include <vector>

#include "Automat.h"

using namespace std;

Automat::Automat(const int k1, const int m1, const int n1) {
    int k=k1;
    int m=m1;
    int n=n1;                                                 
    int Qa[m];
    int Delta[n][2];
};

void Automat::insertQa(Automat *automat, int QaZeile, int QaEintrag) {
     automat->Qa[QaZeile]=QaEintrag;
};

Um noch einmal das draumherum zu erklären:
Der Benutzer gibt eine Zeile ein. Steht in dieser Zeile 0 0 0, dann wird die Berechnung gestartet, ansonsten ein neuer Automat angelegt. Dieser bekommt dann zuerst die 3 Werte k, m und n, und danach werden die Array's gefüllt. Und dann soll es so weiter gehen, bis 0 0 0 eingegeben wird.

Mein Problem ist nun, dass ich es nicht schaffe, auf die Array's zuzugreifen, um die Daten zu schreiben/zu lesen. So wie es jetzt ist, sagt er immer:

'class Automat' has no member named 'Qa'

Könnt Ihr mir bitte dabei helfen? Ich komme sonst einfach nicht weiter

Schon einmal vielen Dank im Voraus, Ozzy
 
Hallo,

also erstmal sollte hier mal festgehalten werden das du die Definitionen im Konstruktor weglassen kann also statt zb.:
Code:
int *Qa = new int[n];
// reicht ein 
Qa = new int[n];
// da du dieses Flag ja schon in der Klassendefinition beschrieben hast

desweiteren ist der member Qa der KLasse privat und du versuchst über eine Instanz diesen Member abzugreifen. dann musst du diesen public setzen.

Ausserdem ist es ziemlich unsinnig die Arrays mit 0 zu initialisieren also 1 sollte es schon sein.

Und wieso gibst du beim Insert nochmal den Pointer von deiner Instanz mit, ich würde das so machen.

Code:
void Automat::insertQa(int QaZeile, int QaEintrag) 
{
     this->Qa[QaZeile]=QaEintrag;
};

Abschliessend noch die KLassendef. deiner Member und der Konstruktor zu deinem Automaten
Code:
private:  
            int *Qa;
            int **Delta;

Code:
Automat::Automat(const int m, const int n)
{
  
 // Member sollten KLassenmember sein sonst nützen sie dir nichts-> also nicht wie hier
  Qa = new int[m];
  Delta = new int*[n];

  int iCounter = -1;
  while(++iCounter < n)
     pDelta[iCounter] = new int[2];

}


so ungefähr müsste das hinhauen. ICh würde allerdings das Array der Automaten von Main aus steuern also Automat *pAutomat = new pAutomat[n]; Dafür brauchst du aber Standardkonstruktor Automat::Automat().



Grüße
R.
 
das mit den "int *pValue = new int[m];" habe ich nicht so ganz verstanden.
Da die Arrays dynamisch sind, wird der benötige Speicher zur Laufzeit mit dem "new"-Operator reserviert, der einen Zeiger auf den Speicherbereich zurückgibt. Der muss im Destruktor wieder freigegeben werden.

Die Variablen, die du im Konstruktor deklarierst, sind nur dort sichtbar. Sollen sie in der ganzen Klasse verwendet werden, müssen sie als Member der Klasse deklariert werden (wie du es ja im auskommentieren Bereich schon versucht hast).

Die Klasse sollte damit etwa so aussehen:
C++:
// .h 
#ifndef AUTOMAT_H
#define AUTOMAT_H

class Automat  
{
public:
    Automat(const int k, const int m, const int n);
    ~Automat();

    void insertQa(int QaZeile, int QaEintrag);

private:
    int m_k, m_m, m_n;  // Member-Variablen mit vorangestellten "m_" kennzeichnen
    int *m_pQa;
    int (*m_pDelta)[2];
};
#endif

// .cpp
#include "Automat.h"

Automat::Automat(const int k, const int m, const int n)
{
    m_k = k; m_m = m; m_n = n;

    m_pQa    = new int[m];
    m_pDelta = new int[n][2];
}

Automat::~Automat()
{
    delete [] m_pQa;
    delete [] m_pDelta;
}

void Automat::insertQa(int QaZeile, int QaEintrag)
{
    m_pQa[QaZeile] = QaEintrag;
}
Gruß MCoder
 
Hi,

danke für die Anwort; habe es jetzt mit Vektoren gemacht, da muss man sich wenigstens keine Gedanken um die Größe machen...
Aber auf jeden Fall vielen Dank für Eure zahlreichen Antworten, ich denke, ich habe das jetzt alles soweit verstanden.

MfG, Ozzy
 
Zurück