Forum: Mikrocontroller und Digitale Elektronik c++ initializer list und zusätzlicher Konstruktor Code.


von Clemens M. (panko)


Lesenswert?

Grüße zusammen,

ich habe vor etwa 15 Jahren etwas c++ benutzt und so stehe ich jetzt bei 
einer Art revival sozusagen bei 0. Es brennt mir aber unter den Nägeln 
und ich möchte mich da wieder etwas reinwühlen.

Daher habe ich auch direkt eine vermutlich lächerliche Frage, wäre 
dennoch über Aufklärung froh:

Wenn ich im Konstruktor eine 'initializer list' benutze, aber irgendwie 
dennoch umfangreicheren Konstruktor Code benötige, wie mache ich das?
Im Fall wo ich gerade strauchel habe ich mir vorgenommen, einige meiner 
c libs in c++ umzusetzen... Ich denke aber euch sagt Code mehr als 
Prosa.
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
5
6
#define TWI0  0xB8
7
#define TWI1  0xD8
8
9
//offset Adresses to TWIs Base Adress
10
#define TWI_TWBR(base_adr)  (_SFR_MEM8(base_adr))
11
#define TWI_TWSR(base_adr)  (_SFR_MEM8(base_adr+1))
12
#define TWI_TWAR(base_adr)  (_SFR_MEM8(base_adr+2))
13
#define TWI_TWDR(base_adr)  (_SFR_MEM8(base_adr+3))
14
#define TWI_TWCR(base_adr)  (_SFR_MEM8(base_adr+4))
15
#define TWI_TWAMR(base_adr) (_SFR_MEM8(base_adr+5))
16
17
#else
18
#error Controller not supported
19
#endif
20
21
class myTwi
22
{
23
  public:
24
    uint8_t error_status;
25
    myTwi(uint8_t twi) :_twi_base_adr(twi) { myTwi::InitCode(_twi_base_adr);}
26
27
  private:
28
   const uint8_t _twi_base_adr;
29
30
   static void InitCode(const uint8_t twi);
31
};
32
33
//#include "myTwi.h"
34
35
void myTwi::InitCode(const uint8_t twi) //Zusätzlicher Init-Code für den Konstruktor
36
{
37
  error_status = 0;
38
(...)
39
}

Wenn ich recht verstehe komme ich bei einem const member (der 
Basisadresse des TWI Ports) gar nicht um das initialisieren per list 
drumrum. Die Hardware muss aber ja mit einigen weiteren Befehlen noch in 
Betrieb genommen werden. Kann/sollte ich das dann über so eine 
Hilfsfunktion machen? Oder alles in der liste? Oder ganz anders?


herzlichen Dank!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Na, einfach in den Konstruktor schreiben! Du hast es doch schon gemacht:

Clemens M. schrieb:
> myTwi(uint8_t twi) :_twi_base_adr(twi) {
> myTwi::InitCode(_twi_base_adr);}

Schreib zwischen die geschweiften Klammern halt alles, was du an 
Initialisierung tun möchtest. Wenn es viel Code wird, solltest du den 
Konstruktor nur lediglich vom class Body trennen und in eine .cpp Datei 
packen, anstelle von direkt in den Class Body in seiner .h Datei - denn 
dann ist er automatisch inline und wird u.U. vom Compiler mehrfach ins 
Programm übernommen.
1
class myTwi
2
{
3
  public:
4
    uint8_t error_status;
5
    myTwi(uint8_t twi);
6
    // ...
7
};
8
9
// .cpp Datei:
10
11
myTwi::myTwi (uint8_t twi) : _twi_base_adr (twi) {
12
 // ... Initialisierung ...
13
}

Noch ein paar Kleinigkeiten:

Clemens M. schrieb:
> #include <stdint.h>
Das ist der C Header, in C++ heißt der <cstdint> .

Clemens M. schrieb:
> #define TWI0  0xB8
> #define TWI1  0xD8
Makros sind grundsätzlich gefährlich, da sie eine dumme Textersetzung 
sind. Im Gegensatz zu C, braucht man sie in C++ seltener. Du kannst und 
solltest daher schreiben:
1
static const uint8_t TWI0 = 0xB8;
2
static const uint8_t TWI1 = 0xD8;
So passiert nichts komisches wenn du später versehentlich irgendwo etwas 
anderes "TWI0" nennst, oder eine überladene Funktion/Template mit TWI0 
als Parameter aufrufst. Aber Achtung, gleich kommen die C-Profis die das 
Gegenteil behaupten ;-)

Clemens M. schrieb:
> const uint8_t _twi_base_adr;
Das ist ok so, aber Vorsicht - Namen die mit Unterstrich + 
Großbuchstabe, oder zwei Unterstrichen beginnen, sind in C und C++ 
verboten und der Standard-Library vorenthalten (wie z.B. __twi_base_adr 
oder _Twi_base_adr).

Clemens M. schrieb:
> #if defined(_AVR_ATmega168_) || defined(_AVR_ATmega168P_) ||
> defined(_AVR_ATmega328_) || defined(_AVR_ATmega328P_)
Eine Alternative zu so etwas wäre, den Controller-Typ per 
template-Parameter an die Klasse zu übergeben. So kannst du im selben 
Projekt Code für verschiedene Controller kompilieren. Ist aber zugegeben 
u.U. viel komplizierter und eher akademisch...

von Clemens M. (panko)


Lesenswert?

Danke dir!

Ich habe irgendwie gedacht, dass eine init-liste in der Deklaration des 
Kontruktors stehen muss... Und, wie du sagtest, das dann bei viel Code 
problematisch werden kann.

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.