mikrocontroller.net

Forum: PC-Programmierung Klasse mit einzelnen :


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von C-Noob (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin über eine Schreibweise gestoplert, die ich so noch nie gesehen 
habe.
Lixie::Lixie(const uint8_t pin, uint8_t nDigits):NumDigits(nDigits), NumLEDs(nDigits * LEDsPerDigit){
  leds = new CRGB[NumLEDs];
  led_states = new byte[NumDigits * 3]; // 24 bits for 20 LED states
  colors = new CRGB[NumDigits];
  colors_off = new CRGB[NumDigits];
  digit_brightness = new byte[NumDigits];
  
  build_controller(pin);
}

Ist eine Funktion einer Klasse, okay. Aber was macht der : nach den 
Parametern der Funktion. Scheint ja irgenwie nochmal Variablen zu 
definieren, nur diese Art das zu machen habe ich noch nie gesehen. Weiß 
jemand wie man das nennt, so dass ich das mal Googlen kann?

von Yalu X. (yalu) (Moderator)


Bewertung
1 lesenswert
nicht lesenswert

: Bearbeitet durch Moderator
von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
C-Noob schrieb:
> Hallo,
>
> ich bin über eine Schreibweise gestoplert, die ich so noch nie gesehen
> habe.
> Lixie::Lixie(const uint8_t pin, uint8_t nDigits):NumDigits(nDigits),
> NumLEDs(nDigits * LEDsPerDigit){
...
> Ist eine Funktion einer Klasse, okay.

Nein, das ist ein Constructor.
Die Liste nach dem : ist die sogenannte "initializer list".

EDIT: Yalu war schneller :-)

: Bearbeitet durch User
von C-Noob (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Super, danke. Jetzt hat das Kind einen Namen.

von MaWin (Gast)


Bewertung
-8 lesenswert
nicht lesenswert
Die Frage wäre, wozu man das braucht.

Stell dir eine Klasse vor, deren Contructor zwingend einen Parameter 
benötigt, es gibt keinen Constructor ohne Parameter.
class x
{
public:
  x(int a);
}
Ein Element dieser Klasse soll nun Membervariable einer anderen Klasse 
werden
class y
{
  x my_x;
public:
  y();
}
Man kann nun im Contructor von y nicht einfach x erzeugen
y::y()
{
  // initialisierung
  my_x=x(4);
}
weil es dann eine Phase gibt zwischen dem Anfang von y::y und dem Teil 
wo hier der Kommentar // Initialisierung streh bis zum my_x = x(4); wo 
es das my_x zwar syntaxmässig gibt, es aber nicht erzeugt werden konnte, 
weil es für ihn keinen Constructor ohne Parameter gibt und C++ ja nicht 
wissen kann welchen Parameter es hätte einsetzen sollen.

Weil das nicht geht, gibt es einen Compilerfehler. Der einzige Weg 
drumrum ist die Initializer List die vor dem eigentlichen Code des 
Constructors ausgeführt wird
y::y():my_x(4)
{
  // initialisiert
}
Dieser hack, um syntaktisch doch das zu ermöglichen, was eigentlich 
nicht geht, hat den Nachteil das der Initializer vor dem eigentlichen 
Contructor code steht und keine Berechnungen durchgeführt werden können, 
um zum Parameter zu kommen.

Da braucht es dann eine Funktion:
int calcparm(void)
{
   time_t t;
   time(&t);
   struct tm * now=localtime(t);
   return now.tm_min+now.tm_sec;
}
y::y:my_x(calcparam())
{
  // bingo
}
Diese kranke Syntax erlaubt es nicht, 2 member-variablen auf derselben 
Teilberechnung aufzusetzen, weil die calcparm Funktionen keine 
gemeinsamen Variablen nutzen können.
int calcsec(void)
{
  time t;
  time(&t);
  struct tm *now=localtime(t);
  return now.tm_sec;
}
int calcmin(void)
{
  time t;
  time(&t);
  struct tm *now=localtime(t);
  return now.tm_min;
class 
{
  x my_sec;
  x my_min;
public:
  y():my_sec(calcsec()),my_min(calcmin())
  {
  }
}
Es geht nicht, min und sec aus derselben Zeit t abzuleiten, sondern man 
muss sie 2 Mal holen. C++ ist ein unreifer hack.

von BobbyX (Gast)


Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
> Ein Element dieser Klasse soll nun Membervariable einer anderen Klasse
> werden

Wer so etwas schreibt hat nix von C++ oder OOP verstanden....

von C-Noob (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo MaWin,

danke für die ausführliche Beschreibung, in welchen Fällen diese 
Initialisierung zum Tragen kommen kann. In dem Code gibt es zwar keine 
weiteren Klassen. Zumindest werden die Werte NumDigits und NumLEDs noch 
in anderen Funktionen der gleichen Klasse verwendet.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
MaWin schrieb:
> Weil das nicht geht, gibt es einen Compilerfehler.

Blödsinn.

MaWin schrieb:
> hat den Nachteil das der Initializer vor dem eigentlichen
> Contructor code steht und keine Berechnungen durchgeführt werden können,
> um zum Parameter zu kommen.

Nochmal Blödsinn.

von Wilhelm M. (wimalopaan)


Bewertung
2 lesenswert
nicht lesenswert
MaWin schrieb:
> C++ ist ein unreifer hack.

Nur für jemanden, der so absolut keine Ahnung hat, wie Du.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Eric B. schrieb:
>> Ist eine Funktion einer Klasse, okay.
>
> Nein, das ist ein Constructor.

Doch, ein ctor ist auch eine Elementfunktion, nur eben eine besondere.

Deswegen heißen bspw. std-ctor, cctor, mctor, cassign-op, massign-op und 
dtor auch special-member-functions.

von Dirk K. (merciless)


Bewertung
0 lesenswert
nicht lesenswert
Die initializer list kann auch verwendet werden,
um andere Konstruktoren aufzurufen. Diese können
aus der eigenene Klasse sein oder geerbt.

merciless

von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht lesenswert
Dirk K. schrieb:
> Die initializer list kann auch verwendet werden,
> um andere Konstruktoren aufzurufen. Diese können
> aus der eigenene Klasse sein oder geerbt.

Ja, genau:

Kleiner Fallstrick: die delegate-ctor müssen das erste Element der 
init-list sein.

von Dirk K. (merciless)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Kleiner Fallstrick: die delegate-ctor müssen das erste Element der
> init-list sein.
Ich hoffe der TO liest eine gute Dokumentation
der initializer list, es gibt ja noch mehr
Fallstricke ;)

Meine Empfehlung: Sparsam verwenden.

merciless

von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht lesenswert
Dirk K. schrieb:
> Ich hoffe der TO liest eine gute Dokumentation
> der initializer list

Du meinst "member initializer list", sonst schaut er bei 
<initializer_list> ;-)

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
> Stell dir eine Klasse vor, deren Contructor zwingend einen Parameter
> benötigt, es gibt keinen Constructor ohne Parameter.

Wenn das so ist, es auch einen (guten) Grund dafür geben. In dem Fall 
sollte man in der grundlegende Struktur seiner Daten darauf Rücksicht 
nehmen.

MaWin schrieb:
> Man kann nun im Contructor von y nicht einfach x erzeugeny::y()
> {
>   // initialisierung
>   my_x=x(4);
> }

C++ (wie C) unterscheidet halt im Zusammenhang mit Variablen (u.a) 
Deklaration, Definition, und Zuweisung.
Abgesehen davon gibt es seit ca. 2011 sowas wie C++11.

Oliver

von mh (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dirk K. schrieb:
> Meine Empfehlung: Sparsam verwenden.

Wenn du std::initilizer_list meinst kann ich dir zustimmen. member 
initilizer lists, sollte man dagegen immer nutzen, wenn möglich. Damit 
hat man schon die halbe Strecke zur exception safety geschafft. 
Zusätzlich ist es schneller und sparsamer und meiner Meinung nach 
deutlich besser lesbar, wenn korrekt formatiert.

von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht lesenswert
mh schrieb:
> Wenn du std::initilizer_list meinst kann ich dir zustimmen. member
> initilizer lists, sollte man dagegen immer nutzen, wenn möglich. Damit
> hat man schon die halbe Strecke zur exception safety geschafft.

Sehr richtig.
Und damit sich nachträglich keine Fehler einschleichen: 
in-class-initializer.

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Sehr richtig.
> Und damit sich nachträglich keine Fehler einschleichen:
> in-class-initializer.

Auf jeden Fall. Was dann aber eben keine member initializer lists mehr 
sind.

Oliver

von mh (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> in-class-initializer

Das hat allerdings wieder den Nachteil, dass man an mindestens zwei 
Stellen gucken muss wie Member initialisiert wurden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.