Klassen instanziieren und übergeben

Hallo zusammen, ich versuche jetzt schon ewige Zeiten eine saubere Abstarktion für eine Kommunikation mit mehreren verschiedenen Kommunikationstechniken zu erstellen, aber ich komme einfach nicht klar.
Ich habe aktuell Implementierungen für die Techniken (I2C, Bluetooth und Serial). Die Jeweiligen Implementierungen erben von der Basis und überschreiben die dort deklarierten Member. Um die Techniken zusammen zu bringen und zu switchen habe ich eine Klasse (Manager) die die Techniken in die Basisklasse der Techniken instanziieren sollen( so stellt die Basis ein Interface dar). Zu guter Letzt habe ich eine Klasse die dann die Daten die ankommen spezifiziert und weiter verarbeitet. Ich arbeite normal mit C# dort ist es einfach komplexe Klassen in den Parametern einfach durch zu reichen und mit ihnen dann zu arbeiten. Aber mit C++ komm ich nicht klar. Wie kann ich z.B. im Setup- Teil eine Klasse instanziieren sie in den Parametern in eine andere rein geben und dann damit arbeiten? Ich kann mit den Zeigern nicht wirklich was anfangen.

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

(Nicht nur) meine Erfahrung mit der Initialisierung von C++ Klassen: erst instantiieren und dann mit einem Methodenaufruf initialisieren.

Objekte sollten als Referenzen übergeben werden, nicht als Pointer.

Ansonsten: was ist an Stream als bereits vorhandener Basisklasse auszusetzen?

@manu_m
Im Prinzip:
wenn du eine Referenz auf Stream vorsiehst, dann kannst du den Stream später mit allen Klassen die von Stream erben nutzen.

Theoretisch jedenfalls.

Vermutlich ist es aber notwendig dass du dir einen Layer einziehst der die Kommunikation mit deiner Transport-Schicht (I2C, Bluetooth, Serial) abstrahiert.
Beispiel:
du machst dir für I2C, Bluetooth, Serial je einen Wrapper der ein .send(Mytype irgendwas) zur Verfügung stellt. Bei der Klassennlage übergibst du dann eine Referenz auf deinen Kommunikations-Wrapper und rufst in deiner Klasse den .send(MiteinemWert) deines (per Referenz übergebenen) Wrappers auf.

Andere Variante: Er nimmt Print als Basisklasse, dann braucht er nur die Methode

virtual size_t write(uint8_t);

für jede Übertragungsart anzulegen, der Rest wird von Print geerbt.

Gruß Tommy

Mir geht's jetzt eigentlich nicht um eine direkte Lösung für das Problem, sondern allgemein um den Lerneffekt. ich würde das gern in C++ nachstellen => Dependency injection.

C#

 public class I2CCommunication : ICommunication
    {
        ICommunicatorManager _commManager;

        public I2CCommunication(ICommunicatorManager commManager) { 
            _commManager = commManager;
        }

        public void pushToManager()
        {
            _commManager.machWasMitDenDaten(new int[5]);
        }
    }

ich weis nicht was c# mit den Zeilen macht, aber das kompiliert ohne Warnung mit dem Arduino Framework:

class ICommunication {};
class ICommunicatorManager {
  public:
    void machWasMitDenDaten(int foo[5]) {
      (void)foo;
    }
};

class I2CCommunication : public ICommunication {
  public:
    ICommunicatorManager _commManager;

    I2CCommunication(ICommunicatorManager commManager) : _commManager (commManager) {}

    void pushToManager() {
      _commManager.machWasMitDenDaten(new int[5]);
    }
};



void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Ohne konkreten Anwendungsfall bin ich dann draußen.

Es geht:

  • Setter Injection
  • Constructor Injection
  • Injection über Template Parameter.

Vielen Dank für das Beispiel @noiasca
Ich hatte einen kleinen Denkfehler, jetzt klappt es!
Auch vielen Dank an die anderen, die mir ihre Zeit geschenkt haben!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.