Forum: PC-Programmierung Verwendung eines Konstruktors


von Gernot (Gast)


Lesenswert?

Für ein Projekt von mir versuche ich jetzt mit Klassen zu arbeiten. Beim 
erstellen eines Objekts sind aber ein Fehler aufgetreten mit denen ich 
nicht gerechnet habe, und ich hoffe ihr könnt mir da weiter helfen.

Wenn ich keinen eigenen Konstruktor habe werden die Variablen der Klasse 
nicht initialisiert (ich dachte das die dann standardmäßig mit 0 
initialisiert werden.)
Beim selber schreiben bin ich mir aber nicht sicher wie ich ihn 
defnieren muss. Mom hab ich das ganze so gemacht:
1
class Name
2
{
3
  char var1;
4
  float var2;
5
6
  Name(int a);
7
8
  public:
9
    
10
    //Methoden
11
};
Bin mir eigentlich recht sicher das das so funktionieren sollte. Wenn 
ich dann aber ein Objekt erstelle bekomme ich die Fehlermeldung: no 
matching function to call Name::Name.
Muss ich den Konstruktor in der main() extra aufrufen? Wenn ja wie?

Hoffe ihr könnt mir da weiterhelfen,

mfg
Gernot

von Sascha B. (sbader)


Lesenswert?

Deiner Klasse fehlt noch der Default Konstruktor in der Form

Name :: Name ()
{
  // hier alles initialisieren
  var1=' ';
  var2=0.0;
  // ...
}

Diesen müßtest Du nicht explizit aufrufen.

Im Beispiel oben hast Du noch einen Konstruktur Name(int a) deklariert. 
Damit Du ihn benutzen kannst muss er auch definiert werden in der Form

Name :: Name(int a)
{
   // hier was mit a machen?
}

Um diesen Konstruktor zu verwenden, mußt Du z.B. in main() sowas 
schreiben

Name a = new Name(123);

von Martin Cibulski (Gast)


Lesenswert?

Hallo Gernot,

der Konstruktor in Deinem Code braucht einen Parameter a.
Dann muss die Variable auch angelegt werden mit z.B.

Name N = Name(5); (oder so ähnlich)

Wenn im Code nur die Variable ohne Parameter a angelegt wird,
(also nur: Name N;), dann braucht man einen Standard-Konstruktor
ohne Parameter.

class Name
{
  char var1;
  float var2;

  Name();  // Standard-Konstruktor

  public:

    //Methoden
};

Der Compiler sucht immer den passenden Funktionsaufruf mit
genau den passenden Parametern und kann diesen wohl nicht finden.

Gruß,
Martin

von Sascha B. (sbader)


Lesenswert?

Ach ja, der Konstruktor sollte normalerweise auch hinter dem "public:" 
stehen, sonst kannst Du aus main heraus nicht drauf zugreifen.
Hier mal ein lauffähiges Beispiel + Bildschirmausgabe:

Default Konstruktor var1=
int Konstruktor a=1
int Konstruktor a=2


#include <cstdlib>
#include <iostream>

using namespace std;

class Name
{
  char var1;
  float var2;
  int x;

  public:

  Name();
  Name(int a);
    //Methoden
};

Name::Name()
{
   cout << "Default Konstruktor var1=" << var1 << endl;
}


Name :: Name (int a)
{
   x=a;
   cout << "int Konstruktor a=" << a << endl;
}


int main(int argc, char *argv[])
{
    Name x;
    Name x2(1);

    Name* x3 = new Name(2);

    system("PAUSE");
    return EXIT_SUCCESS;
}

von Rolf Magnus (Gast)


Lesenswert?

> Wenn ich keinen eigenen Konstruktor habe werden die Variablen der
> Klasse nicht initialisiert (ich dachte das die dann standardmäßig mit 0
> initialisiert werden.)

Member-Variablen von eingebauten Typen (wie z.B int oder float) bleiben 
uninitialisiert. Bei Klassen wird der Default-Kontruktor aufgerufen.

>  Name(int a);
>
> Bin mir eigentlich recht sicher das das so funktionieren sollte. Wenn
> ich dann aber ein Objekt erstelle bekomme ich die Fehlermeldung: no
> matching function to call Name::Name.

Du hast einen Konstruktor definiert, der einen Wert als Parameter 
erwartet. Dann mußt du bei der Erzeugung des Objekts diesen Parameter 
aber auch angeben.

> Muss ich den Konstruktor in der main() extra aufrufen? Wenn ja wie?

Der wird beim Erzeugen eines Objekts immer automatisch aufgerufen. Du 
kannst z.B. ein Objekt "name" erzeugen mit:  Name name(5);

@Sascha Bader:

> Name :: Name ()
> {
>  // hier alles initialisieren

Eigentlich nicht. Hier sind alle Initialisierungen - sofern überhaupt 
welche stattfinden - schon abgelaufen. Was folgt, sind Zuweisungen.

>   var1=' ';
>   var2=0.0;
>   // ...
> }

Eine echte Initialisierung würde so aussehen:

Name :: Name ()
  : var1(' '),
    var2(0.0)
{
   // ...
}

> Um diesen Konstruktor zu verwenden, mußt Du z.B. in main() sowas
> schreiben
>
> Name a = new Name(123);

new gibt einen Zeiger zurück, also müßte es heißen:
1
Name* a = new Name(123);

Aber dynamisch angelegte Objekte sollte man nur verwenden, wenn man sie 
auch wirklich braucht. Wenn man nicht gerade eine "smart-pointer"-Klasse 
verwendet, muß man nämlich sonst jedes von diesen Objekten auch wieder 
manuell freigeben.

von Sascha B. (sbader)


Lesenswert?

@Rolf

>Eigentlich nicht. Hier sind alle Initialisierungen - sofern überhaupt
>welche stattfinden - schon abgelaufen. Was folgt, sind Zuweisungen.
>Eine echte Initialisierung würde so aussehen:

Da hast Du natürlich Recht. Initialisierunglisten sind hier die bessere 
Wahl.  Ist schon besser wenn man von Anfang an den richtigen Stil 
vermittelt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.