ich versuche mich etwas mit der Combie-Lib auseinander zu setzen und mein C++ Wissen zu erweitern. Dazu habe ich mit CombiePin angefangen. Nun drängt sich mir eine Frage auf. Dadurch, dass ein Pin Objekt aus einem Template erzeugt wird, kann ich kein Array aus Pins erstellen.
Ich bin also (mit meinem momentanen Wissensstand) gezwungen, einzelne Objekte anzulegen, die ich nicht in einer Schleife abarbeiten kann. Wie kann man das möglich machen?
Eine Erweiterung der Frage:
In anderen Zusammenhängen hast Du (@combie) mit einer abstrakten Basisklasse Arrays aus Zeigern auf die Basisklasse erzeugt. Wenn man das macht, kann nur auf die Methoden zugegriffen werden, die auch in der Basisklasse deklariert wurden. Ein Zugriff auf (nicht virtuelle) Methoden, die nur in der von der Basisklasse abgeleiteten Klasse vorkommen, ist dann ja nicht möglich. Oder Doch?
Danke für das Beispiel. Das ist ein ausgefuchstes Baukastensystem. Da muss ich erst mal weiter mit probieren. Es ist aber schon mal gut bestätigt zu bekommen, dass Arrays tatsächlich nur über Interface-Klassen zu „bauen“ sind und es nicht doch noch irgend einen anderen Mechanismus gibt.
Der springende Punkt ist halt, dass in einem Array alle Daten vom gleichen Type sein müssen. Bei mir das ein Zeiger auf Task.
Ist kein vollständiger Datentype.
Er braucht auch noch seine Template Parameter
Jetzt ist es ein Datentype. Jetzt kann man auch eine Instanz davon erzeugen.
Im Grunde ist es das Arduino Pin Durchnummerieren, welches die andere Wege unterbindet.
Und eben der Wunsch, die eigentliche Pin Operation so schlank wie möglich zu machen.
Ein paar wenige Takte gehen für jede Pin Operation drauf. Irgendwas um 1 bis 3 pro Zugriff.
Ein digitalWrite() braucht da eher an die 100 Takte.
Da werden 3 Instanzen erzeugt (könnte man meinen).
Das ist allerdings völlig kostenlos.
Kein Takt und kein Speicher(RAM/Stack) wird dafür genutzt, nur wenige ASM Statements landen im Flash
Aber da die Tasks verschiedene Template-Parameter haben, sind sie doch eigentlich auch verschiedene Typen?
Und Zeiger auf verschiedene Typen kann man doch eigentlich auch nicht mischen?
[Edit]
Äh, in deinem Beispiel fehlen die Definitionen von Taster, Pumpe, Druck
[/Edit]
Es werden 3 Instanzen von Combie::Pin erzeugt. (und wegoptimiert)
Druck und Taster werden nach ihrem aktuellen Zustand gefragt, die Zustände logisch &&(AND) verknüpft und das Ergebnis in die Pumpe geschickt.
Dass das was in init() mit Pumpe{}.init(); gemacht wurde, auch für die neue Instanz
Pumpe{} in run() gilt, liegt daran, dass es sich nur auf den darin versteckten Pin auswirkt.
Wenn man wollte, könnte man in PumpemAbhandlung auch (private) Membervariable vom Typ Pumpe, Druck, Taster oder Sonstwas definieren, die dann in run() zur Verfügung stünden, da statt Task::run() tatsächlich PumpemAbhandlung::run() läuft.
(z.B. wenn man sich da einen alten Hysterese-Zustand oder gleitenden Mittelwert oder so merken will)
Andere combie-Elemente reagieren empfindlicher auf Neuerzeugen und Wegoptimieren.