Klasse mit einzelnen :

Gast #6059118
Hallo,

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

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?
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 :-)
Gast
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.
1
class x
2
{
3
public:
4
  x(int a);
5
}
Ein Element dieser Klasse soll nun Membervariable einer anderen Klasse 
werden
1
class y
2
{
3
  x my_x;
4
public:
5
  y();
6
}
Man kann nun im Contructor von y nicht einfach x erzeugen
1
y::y()
2
{
3
  // initialisierung
4
  my_x=x(4);
5
}
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
1
y::y():my_x(4)
2
{
3
  // initialisiert
4
}
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:
1
int calcparm(void)
2
{
3
   time_t t;
4
   time(&t);
5
   struct tm * now=localtime(t);
6
   return now.tm_min+now.tm_sec;
7
}
8
y::y:my_x(calcparam())
9
{
10
  // bingo
11
}
Diese kranke Syntax erlaubt es nicht, 2 member-variablen auf derselben 
Teilberechnung aufzusetzen, weil die calcparm Funktionen keine 
gemeinsamen Variablen nutzen können.
1
int calcsec(void)
2
{
3
  time t;
4
  time(&t);
5
  struct tm *now=localtime(t);
6
  return now.tm_sec;
7
}
8
int calcmin(void)
9
{
10
  time t;
11
  time(&t);
12
  struct tm *now=localtime(t);
13
  return now.tm_min;
14
class 
15
{
16
  x my_sec;
17
  x my_min;
18
public:
19
  y():my_sec(calcsec()),my_min(calcmin())
20
  {
21
  }
22
}
Es geht nicht, min und sec aus derselben Zeit t abzuleiten, sondern man 
muss sie 2 Mal holen. C++ ist ein unreifer hack.
Gast
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.
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
Gast
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.
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.