Klasse mit einzelnen :

Gast #6059118
Lesenswert?

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?
#6059125
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 :-)
Gast #6059228
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.
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 #6059370
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.
#6060494
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
Gast #6060725
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren