Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Klasse i nArray Elementen erstellen

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
02.09.2011, 01:46 Uhr
Haishi



Hallo,

ich habe gerade eine kleine Klasse geschrieben und wollte diese jetzt in Array Elementen erstellen, das klappt nur nicht so ganz wie ich mir das vorstellte, erst ein mal die Klasse:


C++:
class player
{
  public:
      player(int v);
      ~player(void);

      int getHealth(void);
  private:
      int health;
};

player::player(int v)
{
  cout << "Konstruktor" << endl;
    health = v;
}

player::~player(void)
{
  cout << "Destruktor" << endl;
}

int player::getHealth(void)
{
  return health;
}



In meiner main Funktion löse ich das bis jetzt so:


C++:
    player *Spieler1 = new player(120);
    player *Spieler2 = new player(120);

    cout << "Spieler 1 hat " << Spieler1->getHealth()
         << " Lebenspunkte!" << endl;
    cout << "Spieler 2 hat " << Spieler2->getHealth()
         << " Lebenspunkte!" << endl;

    delete Spieler1;
    delete Spieler2;



Ich suche jetzt Anregungen und Vorschläge wie ich "Spieler1" und "Spieler2" in einem Array verpacken kann.

Dieser Post wurde am 02.09.2011 um 01:47 Uhr von Haishi editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
02.09.2011, 07:25 Uhr
Tommix



'Morgen,

Zitat von Haishi:

..., das klappt nur nicht so ganz wie ich mir das vorstellte, ...


Wie stellst Du Dir es denn vor?
Eine einfacher Ansatz wäre:

C++:
int main()
{
    enum {player_count = 2};

    player* spieler[player_count] = {new player(120), new player(120)};

    for (int i = 0; i < player_count; ++i)
        cout << "Spieler " << i+1 << " hat " <<
        spieler[i]->getHealth() << " Lebenspunkte!" << endl;

    for (int i = 0; i < player_count; ++i)
        delete spieler[i];

    return 0;
}


Wobei der Einsatz eines Containers wie std::vector, je nachdem was Du machen willst, von Vorteil sein könnte.

Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.09.2011, 12:18 Uhr
0xdeadbeef
Gott
(Operator)


Es sieht mir nicht danach aus, als müssten die Objekte hier auf den Heap. Wie wär's mit

C++:
player spieler[] = { player(120), player(120) };

for(int i = 0; i < 2; ++i) {
  cout << "Spieler " << i + 1 << " hat " << spieler[i].getHealth() << " Lebenspunkte." << endl;
}


?

Wenn die Objekte tatsächlich auf den Heap müssen, wäre es sinnvoll, in irgendeiner Form RAII zu betreiben. Mit Standardmitteln etwa std::vector<std::tr1::shared_ptr<player> >, ansonsten hat Boost eine Reihe spezialisierter Container für genau solche Fälle. Nacktes new/delete ist der Exceptionsicherheit ausgesprochen abträglich.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
02.09.2011, 14:32 Uhr
Haishi



Wunderbar, mit dem Code von 0xdeadbeef bin ich 100% zufrieden.

Blöd ist nur das es zwar geht, ich aber nicht 100% nachvollziehen kann warum ;) Aber das kommt vielleicht noch^^

Nun bekomme ich aber einen Fehler beim Auflösen der Array Elemente:


C++:
for(int i = 0; i < 2; i++)
      delete spieler[i];




Zitat:

error C2440: 'delete': 'player' kann nicht in 'void *' konvertiert werden



Außerdem würde mich mal folgendes Interessieren:


C++:
player spieler[] =
{
  player(120),
  player(170)
};



Wieso erstellt der Compiler mir denn hier 8 Elemente?


Zitat:

Spieler 0 hat 120 Lebenspunkte
Spieler 1 hat 170 Lebenspunkte
Spieler 2 hat -858993460 Lebenspunkte (der is wohl tod :D)
Spieler 3 hat 2489632 Lebenspunkte
Spieler 4 hat 16930267 Lebenspunkte
Spieler 5 hat 1 Lebenspunkte
Spieler 6 hat 2489648 Lebenspunkte
Spieler 7 hat 16919439 Lebenspunkte


Dieser Post wurde am 02.09.2011 um 14:32 Uhr von Haishi editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
02.09.2011, 14:47 Uhr
0xdeadbeef
Gott
(Operator)


Das sind dann Stack-Objekte, die müssen nicht von Hand gelöscht werden - sie werden automatisch zerstört, wenn ihr Scope verlassen wird.

Gemeint ist das etwa so:

C++:
#include "player.h"

#include <cstddef>
#include <iostream>

// Bisschen Template-Magie. Gibt die Elementanzahl von Arrays zurück,
// lehnt Zeiger ab.
template<typename T, std::size_t N>
std::size_t array_size(T(&)[N]) { return N; }

int main() {
  player spieler[] = { player(120), player(120) };

  for (int i = 0; i < array_size(spieler); ++i) {
    std::cout << "Spieler " << i+1 << " hat "
              << spieler[i].getHealth() << " Lebenspunkte!" << endl;
  }
}


Dass du acht Ausgaben für zwei Spieler kriegst, wird (vermute ich) wohl daran liegen, dass du sizeof missverstehst. Hast du in deinem Code

C++:
for(int i = 0; i < sizeof(spieler); ++i) { // <-- Fehler!


stehen? Vermutlich sind ints bei dir 4 Byte breit, und da player nur einen int beinhaltet, wird player auch 4 Byte groß sein. Dann liefert sizeof(spieler) 8 zurück (spieler ist zwei player breit, 2 * 4 = 8), und du interpretierst spieler dementsprechend als Array der Länge 8. Der hinter dem Array liegende Speicher wird dabei schlicht falsch interpretiert, und du kriegst diesen Blödsinn dabei heraus.

Natürlich erzeugt das undefiniertes Verhalten - so was kann locker auch abstürzen oder irgendetwas anderes machen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 02.09.2011 um 14:52 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
02.09.2011, 14:52 Uhr
Haishi



Jaa funktioniert auch wunderbar und wieder verstehe ich in diesen 2 Zeilen FAST nur Bahnhof

Zumindest in der Zeile mit dem template..
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
02.09.2011, 14:55 Uhr
0xdeadbeef
Gott
(Operator)


Das ist ein vegleichsweise einfacher Template-Metaprogrammierungstrick. In Funktionsvorlagen wie diesen kann der Compiler die Template-Parameter aus den Aufrufsparametern herleiten. Wenn ich

C++:
array_size(spieler)


schreibe, leitet der Compiler daraus eine Funktion

C++:
std::size_t array_size(player (&)[2]) { return 2; }


ab (T = player, N = 2). In C hätte man stattdessen

C++:
(sizeof(spieler) / sizeof(*spieler))


geschrieben, aber das gibt einem mit Zeigern blödsinnige Werte heraus - viele Anfänger stolpern in C darüber. Die Funktionsvorlage array_size dagegen liefert einen Compilerfehler, wenn man sie auf einen Zeiger anzuwenden versucht.

Das (&) bedeutet, dass der Parameter als Referenz auf ein Array betrachtet werden soll; das ist notwendig, weil Arrays, wenn sie direkt übergeben werden, zu einem Zeiger zerfallen und die Dimensionsinformation, die ich hier abgreifen will, verloren ginge.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 02.09.2011 um 14:58 Uhr von 0xdeadbeef editiert.
 
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: