Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.sci.electronics > #203890 > unrolled thread
| Started by | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| First post | 2016-03-09 18:14 +0100 |
| Last post | 2016-03-11 09:14 +0100 |
| Articles | 20 on this page of 25 — 6 participants |
Back to article view | Back to de.sci.electronics
C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 18:14 +0100
Re: C++ method pointer? Christian Zietz <newsgroup.1001@chz.xyz> - 2016-03-09 18:24 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 19:43 +0100
Re: C++ method pointer? Christian Zietz <newsgroup.1001@chz.xyz> - 2016-03-09 20:03 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 20:29 +0100
Re: C++ method pointer? Christian Zietz <newsgroup.1001@chz.xyz> - 2016-03-09 20:47 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 19:57 +0100
Re: C++ method pointer? Thorsten Böttcher <thorsten_nospam@gmx.net> - 2016-03-09 19:49 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 20:11 +0100
Re: C++ method pointer? Thorsten Böttcher <thorsten_nospam@gmx.net> - 2016-03-09 20:35 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 22:31 +0100
Re: C++ method pointer? Thorsten Böttcher <thorsten_nospam@gmx.net> - 2016-03-10 06:45 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-10 16:59 +0100
Re: C++ method pointer? Marc Santhoff <m.santhoff@t-online.de> - 2016-03-09 20:47 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-09 22:33 +0100
Re: C++ method pointer? Christian Zietz <newsgroup.1001@chz.xyz> - 2016-03-09 23:11 +0100
Re: C++ method pointer? Marc Santhoff <m.santhoff@t-online.de> - 2016-03-10 01:29 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-11 13:24 +0100
Re: C++ method pointer? Edzard Egberts <ed_09@tantec.de> - 2016-03-10 08:51 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-10 16:33 +0100
Re: C++ method pointer? Heinz Saathoff <newshsaat@arcor.de> - 2016-03-10 09:14 +0100
Re: C++ method pointer? Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2016-03-10 16:42 +0100
Re: C++ method pointer? Edzard Egberts <ed_09@tantec.de> - 2016-03-10 19:12 +0100
Re: C++ method pointer? Edzard Egberts <ed_09@tantec.de> - 2016-03-11 08:04 +0100
Re: C++ method pointer? Heinz Saathoff <newshsaat@arcor.de> - 2016-03-11 09:14 +0100
Page 1 of 2 [1] 2 Next page →
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 18:14 +0100 |
| Subject | C++ method pointer? |
| Message-ID | <dkb40lFph51U1@mid.individual.net> |
Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
mit einem Methoden-Pointer erledigen läßt :-(
Ewas konkreter: Es geht um die Klasse IRrecv aus der Arduino IRremote
Bibliothek. Sie enthält Dekodierer für verschiedene Protokolle, z.B.
decodeNEC(), decodeSony(), die ich schon von allem überflüssigen Ballast
befreit habe. Nun möchte ich einen Pointer auf eine dieser Methoden
innerhalb seiner Klasse erzeugen, vorbesetzen und dann aufrufen. Sowas wie:
In der Bibliothek:
class IRrecv {
public:
bool decodeNEC();
bool decodeSony();
...
bool() *Decoder; //??? soll auf eine der o.g. Methoden zeigen
void begin(???); //soll Decoder mit dem übergebenen Parameter
initialisieren
char read(); //soll intern Decoder aufrufen
};
IRecv::read() {
if (*Decoder()) //??? soll die Methode aufrufen
return results.asc;
else
return '?';
}
Im Programm:
IRrecv irrecv(IR_PIN); //erzeugt Instanz (Singleton)
void setup() {
irrecv.begin(&decodeNEC); //??? soll den Pointer initialisieren
}
void loop() {
if (irrecv.available()) {
char data = irrecv.read();
...
}
}
Da die Methode nur innerhalb der (selben) Instanz aufgerufen werden
soll, könnte ein einfacher Pointer ausreichen?
Wie müssen die oben markierten Stellen genau aussehen?
TIA
DoDi
[toc] | [next] | [standalone]
| From | Christian Zietz <newsgroup.1001@chz.xyz> |
|---|---|
| Date | 2016-03-09 18:24 +0100 |
| Message-ID | <dkb4itFpm0sU1@mid.individual.net> |
| In reply to | #203890 |
Hans-Peter Diettrich schrieb: > Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von > denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind > meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das > mit einem Methoden-Pointer erledigen läßt :-( 1. Eine C++-Newsgroup existiert. Dort wäre Deine Frage sogar on-topic. 2. Der lehrbuchhafte Weg in C++ wäre, die decode-Methode als virtuelle Methode in einer Basisklasse zu deklarieren und die tatsächlichen Dekoder dann in davon erbenden Klassen zu implementieren. 3. <https://isocpp.org/wiki/faq/pointers-to-members> Christian -- Christian Zietz - CHZ-Soft - czietz (at) gmx.net WWW: http://www.chzsoft.de/ PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 19:43 +0100 |
| Message-ID | <dkb97bFqtk3U1@mid.individual.net> |
| In reply to | #203892 |
Christian Zietz schrieb: > Hans-Peter Diettrich schrieb: > >> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von >> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind >> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das >> mit einem Methoden-Pointer erledigen läßt :-( > > 1. Eine C++-Newsgroup existiert. Dort wäre Deine Frage sogar on-topic. Sowas dachte ich mir schon ;-) Über die Syntax hinaus geht es mir auch um den Speicherbedarf, und die beste Variante für den Einsatz auf einem µC. Deshalb auch der längliche Verweis auf die Arduino Bibliothek. > 2. Der lehrbuchhafte Weg in C++ wäre, die decode-Methode als virtuelle > Methode in einer Basisklasse zu deklarieren und die tatsächlichen > Dekoder dann in davon erbenden Klassen zu implementieren. Ich dachte auch schon an eine Klasse pro Protokoll, nur bläht das die Bibliothek auf. Das riecht dann irgendwie nach einem Template? Virtuell scheint mir auch überflüssig, denn wenn man ein Objekt der abgeleiteten Klasse erzeugen muß, dann kann man dessen Methoden auch direkt aufrufen. > 3. <https://isocpp.org/wiki/faq/pointers-to-members> Da war ich schon, hilft mir aber nicht bei allen Details :-( Danke für die Hilfe :-) DoDi
[toc] | [prev] | [next] | [standalone]
| From | Christian Zietz <newsgroup.1001@chz.xyz> |
|---|---|
| Date | 2016-03-09 20:03 +0100 |
| Message-ID | <dkbacvFr7hsU1@mid.individual.net> |
| In reply to | #203897 |
Hans-Peter Diettrich schrieb: > Ich dachte auch schon an eine Klasse pro Protokoll, nur bläht das die > Bibliothek auf. Im Quellcode vielleicht. Compiliert kommt ziemlich genau das heraus, was Du mit Deinen händischen Methodenpointern auch machen willst. Jede abgeleitete Klasse hat eine vtable mit einem Pointer auf ihre decode-Methode. > Virtuell scheint mir auch überflüssig, denn wenn man ein Objekt der > abgeleiteten Klasse erzeugen muß, dann kann man dessen Methoden auch > direkt aufrufen. Eben nicht. Du könntest z.B. sowas haben: AbstractDecoder* decoder = AbstractDecoder::createDecoder(x); decodeddata = decoder->decode(data); Je nach Wert von 'x' wird 'decoder' nun zur Laufzeit eine Instanz von SonyDecoder, NECDecoder usw. Trotzdem ruft decoder.decode() immer die passende decode-Methode (und nicht etwa die in AbstractDecoder) auf. Genau *dafür* brauchst Du virtuelle Methoden. => C++-Lehrbuch lesen. Wäre das hier eine C++-NG, würde ich Dir eben ein komplettes Beispiel hintippen, aber in d.s.e ist das doch arg off-topic. Christian -- Christian Zietz - CHZ-Soft - czietz (at) gmx.net WWW: http://www.chzsoft.de/ PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 20:29 +0100 |
| Message-ID | <dkbbsfFrl7lU1@mid.individual.net> |
| In reply to | #203900 |
Christian Zietz schrieb: > Hans-Peter Diettrich schrieb: > >> Ich dachte auch schon an eine Klasse pro Protokoll, nur bläht das die >> Bibliothek auf. > > Im Quellcode vielleicht. Compiliert kommt ziemlich genau das heraus, was > Du mit Deinen händischen Methodenpointern auch machen willst. Jede > abgeleitete Klasse hat eine vtable mit einem Pointer auf ihre > decode-Methode. > >> Virtuell scheint mir auch überflüssig, denn wenn man ein Objekt der >> abgeleiteten Klasse erzeugen muß, dann kann man dessen Methoden auch >> direkt aufrufen. > > Eben nicht. Du könntest z.B. sowas haben: > > AbstractDecoder* decoder = AbstractDecoder::createDecoder(x); > decodeddata = decoder->decode(data); Mir ist schon eingefallen, warum virtuelle Methoden unerwünscht sind (siehe andere Mail). Eigentlich könnte man hier auf Objekte (immer Singletons) ganz verzichten, ich hatte auch schon an einen Aufruf wie if (decodeNEC(ErgebnisVar)) ... //liefert Wert in ErgebnisVar zurück gedacht. Aber leider liegen manche Parameter in der Instanz der Klasse, und es wäre auch aufwendiger, neue Decoder einzufügen. Deshalb möchte ich auch eine weitgehende Kompatibilität mit den vorhandenen Bibliotheken beibehalten. > Je nach Wert von 'x' wird 'decoder' nun zur Laufzeit eine Instanz von > SonyDecoder, NECDecoder usw. Trotzdem ruft decoder.decode() immer die > passende decode-Methode (und nicht etwa die in AbstractDecoder) auf. > Genau *dafür* brauchst Du virtuelle Methoden. => C++-Lehrbuch lesen. Wie gesagt, dynamische Erzeugung ist überflüssig und auf einem schmalbrüstigen µC auch unerwünscht. Meine C++ "Lehrbücher" (Borland C++) sind leider ziemlich alt, und beantworten meine Fragen auch nicht. Mir wäre eine andere Sprache auch lieber, OPL oder Ada, aber für die Verwendung in der Arduino IDE muß es ja unbedingt C oder C++ sein :-( > Wäre das hier eine C++-NG, würde ich Dir eben ein komplettes Beispiel > hintippen, aber in d.s.e ist das doch arg off-topic. Zugegeben, in dieser Gruppe findet sich bereits mehr off-topic als Antworten auf Fragen, aber kurze konkrete Antworten würden helfen, weiteren Traffic überflüssig zu machen :-] DoDi
[toc] | [prev] | [next] | [standalone]
| From | Christian Zietz <newsgroup.1001@chz.xyz> |
|---|---|
| Date | 2016-03-09 20:47 +0100 |
| Message-ID | <dkbcu9Fru91U1@mid.individual.net> |
| In reply to | #203907 |
Hans-Peter Diettrich schrieb: > Mir ist schon eingefallen, warum virtuelle Methoden unerwünscht sind > (siehe andere Mail). Den Grund habe ich allerdings nicht verstanden. Auf alle Decoder zugreifen kannst Du mit virtuellen Methoden doch ebenso. Aber egal, dann müh Dich eben weiter mit Pointern auf Methoden ab... > Wie gesagt, dynamische Erzeugung ist überflüssig und auf einem > schmalbrüstigen µC auch unerwünscht. Dann halt als Makro, wobei eine Basisklasse und virtuelle Methoden weiterhin erforderlich sind. Dann kann der Linker wie gewünscht nicht verwendete Decoder aussortieren. #define GET_DECODER(x) (new x##Decoder) AbstractDecoder* decoder = GET_DECODER(Sony); decoder->decode(data); Christian -- Christian Zietz - CHZ-Soft - czietz (at) gmx.net WWW: http://www.chzsoft.de/ PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 19:57 +0100 |
| Message-ID | <dkba1jFr4knU1@mid.individual.net> |
| In reply to | #203892 |
Christian Zietz schrieb: > 2. Der lehrbuchhafte Weg in C++ wäre, die decode-Methode als virtuelle > Methode in einer Basisklasse zu deklarieren und die tatsächlichen > Dekoder dann in davon erbenden Klassen zu implementieren. In den vorhandenen Bibliotheken gibt es eine universelle decode() Methode, die alle installierten Decoder durchprobiert - die würde mit virtuellen Methoden nicht funktionieren. Die habe ich dann schon mal in eine eigene Klasse IRrecvAll gepackt, so daß sie bei Bedarf (Ausspähen einer unbekannten Fernbedienung) weiterhin verwendet werden kann. Das erfordert dann, daß diese Methode Zugriff auf alle Decoder hat, und diese dann natürlich ins Programm einbindet. Dieser Overhead (Zeit und Speicher) soll unbedingt wegfallen, wenn man nur von einer bestimmten Fernbedienung empfangen möchte. Die vorhandenen Bibliotheken erfordern Eingriffe (#define), wenn man nicht alle Decoder benutzen möchte, und das hat dann wieder unschöne Nebeneffekte, die ich vermeiden möchte. Aber wenn jemand eine einfachere Lösung einfällt, bin ich für jeden Hinweis dankbar :-) DoDi
[toc] | [prev] | [next] | [standalone]
| From | Thorsten Böttcher <thorsten_nospam@gmx.net> |
|---|---|
| Date | 2016-03-09 19:49 +0100 |
| Message-ID | <nbpr73$77j$1@news.albasani.net> |
| In reply to | #203890 |
Am 09.03.2016 um 18:14 schrieb Hans-Peter Diettrich:
> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
> mit einem Methoden-Pointer erledigen läßt :-(
Kann man machen, ist aber unschön. Stichwort Funktoren.
Um Memberfunktionen aufzurufen brauchst Du den Zeiger auf das Objekt.
Wieviel verschiedene Dekoder gibt es denn?
Entweder Du baust Dir ein Interface, und erzeugst Dir passende Objekte
je nachdem was Du brauchst, oder Du erledigst das einfach mit ner
if-Abfrage, oder mit einem switch case Block.
begin(IRecv::DecodeNEC);
IRecv::read()
{
if (decoder==DecoderNEC)
return decodeNEC;
else
return decodeSony();
}
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 20:11 +0100 |
| Message-ID | <dkbar9FrbmbU1@mid.individual.net> |
| In reply to | #203898 |
Thorsten Böttcher schrieb:
> Am 09.03.2016 um 18:14 schrieb Hans-Peter Diettrich:
>> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
>> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
>> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
>> mit einem Methoden-Pointer erledigen läßt :-(
>
> Kann man machen, ist aber unschön. Stichwort Funktoren.
> Um Memberfunktionen aufzurufen brauchst Du den Zeiger auf das Objekt.
Deshalb wollte ich ja die Methode innerhalb des Objekts aufrufen, dann
ist die Instanz ja bereits bekannt (this).
> Wieviel verschiedene Dekoder gibt es denn?
Etwa 10, Tendenz steigend. Zudem hätte ich gerne noch eine Möglichkeit,
die empfangenen Codes über Tabellen in einen einfacheren Datentyp
umzuwandeln, z.B. '0'-'9' für numerische Tasten. Das sollte aber
möglichst ohne komplizierte Programmierung gehen, die meisten Benutzer
haben noch viel weniger Ahnung von C++ als ich ;-)
> Entweder Du baust Dir ein Interface, und erzeugst Dir passende Objekte
> je nachdem was Du brauchst,
Das riecht für mich nach einem Template, und da kenne ich mich auch
nicht (mehr) aus :-(
> oder Du erledigst das einfach mit ner
> if-Abfrage, oder mit einem switch case Block.
>
> begin(IRecv::DecodeNEC);
>
> IRecv::read()
> {
> if (decoder==DecoderNEC)
> return decodeNEC;
> else
> return decodeSony();
> }
Das hat den Nachteil, daß alle angegebenen Decoder ins Programm
eingebunden werden, und das möchte ich vermeiden. Der Linker ist ja
schon so clever, daß er unbenutze Methoden wegläßt, man muß nur noch
vermeiden, daß diese irgendwo in der Bibliothek referenziert werden.
Danke fürs Mitdenken
DoDi
[toc] | [prev] | [next] | [standalone]
| From | Thorsten Böttcher <thorsten_nospam@gmx.net> |
|---|---|
| Date | 2016-03-09 20:35 +0100 |
| Message-ID | <nbpttb$d2q$1@news.albasani.net> |
| In reply to | #203902 |
Am 09.03.2016 um 20:11 schrieb Hans-Peter Diettrich:
> Thorsten Böttcher schrieb:
>> Am 09.03.2016 um 18:14 schrieb Hans-Peter Diettrich:
>>> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
>>> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
>>> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
>>> mit einem Methoden-Pointer erledigen läßt :-(
>>
>> Kann man machen, ist aber unschön. Stichwort Funktoren.
>> Um Memberfunktionen aufzurufen brauchst Du den Zeiger auf das Objekt.
>
> Deshalb wollte ich ja die Methode innerhalb des Objekts aufrufen, dann
> ist die Instanz ja bereits bekannt (this).
Das stimmt, ändert aber nichts daran dass man ihn braucht.
>
>> Wieviel verschiedene Dekoder gibt es denn?
>
> Etwa 10, Tendenz steigend. Zudem hätte ich gerne noch eine Möglichkeit,
Dann ein Interface, bzw. abstrakte Klasse, da es in C++ keine Interfaces
gibt, und dann das passende Objekt erzeugen. Hat Christian bereits
geschrieben.
Das könnte im prinzip Dein Singleton machen.
>> Entweder Du baust Dir ein Interface, und erzeugst Dir passende Objekte
>> je nachdem was Du brauchst,
>
> Das riecht für mich nach einem Template, und da kenne ich mich auch
> nicht (mehr) aus :-(
Nein, dazu braucht man keine Templates.
>> oder Du erledigst das einfach mit ner if-Abfrage, oder mit einem
>> switch case Block.
>>
>> begin(IRecv::DecodeNEC);
>>
>> IRecv::read()
>> {
>> if (decoder==DecoderNEC)
>> return decodeNEC;
>> else
>> return decodeSony();
>> }
>
> Das hat den Nachteil, daß alle angegebenen Decoder ins Programm
> eingebunden werden, und das möchte ich vermeiden. Der Linker ist ja
> schon so clever, daß er unbenutze Methoden wegläßt, man muß nur noch
> vermeiden, daß diese irgendwo in der Bibliothek referenziert werden.
Wenn die Dekoder zur Laufzeit ausgewählt werden sollen, dann müssen Sie
zwangsläufig im Programm sein.
Oder willst Du vor dem Kompilieren entscheiden welcher Dekoder benutzt wird?
MfG
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 22:31 +0100 |
| Message-ID | <dkbj5oFtl63U1@mid.individual.net> |
| In reply to | #203908 |
Thorsten Böttcher schrieb: > Oder willst Du vor dem Kompilieren entscheiden welcher Dekoder benutzt > wird? Ja, den Rest gibt es ja schon. DoDi
[toc] | [prev] | [next] | [standalone]
| From | Thorsten Böttcher <thorsten_nospam@gmx.net> |
|---|---|
| Date | 2016-03-10 06:45 +0100 |
| Message-ID | <nbr1l3$l92$2@news.albasani.net> |
| In reply to | #203920 |
Am 09.03.2016 um 22:31 schrieb Hans-Peter Diettrich: > Thorsten Böttcher schrieb: > >> Oder willst Du vor dem Kompilieren entscheiden welcher Dekoder benutzt >> wird? > > Ja, den Rest gibt es ja schon. Dann mach das doch ganz einfach über eine Präprozessoranweisung, anstatt so etwas kompliziertes wie eine Methodenpointer, der später alle anderen eher verwirrt. Ich ging davon aus dass Du zur Laufzeit den Dekoder auswählen willst. MfG
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-10 16:59 +0100 |
| Message-ID | <dkdk21FemhsU3@mid.individual.net> |
| In reply to | #203949 |
Thorsten Böttcher schrieb: > Am 09.03.2016 um 22:31 schrieb Hans-Peter Diettrich: >> Thorsten Böttcher schrieb: >> >>> Oder willst Du vor dem Kompilieren entscheiden welcher Dekoder benutzt >>> wird? >> >> Ja, den Rest gibt es ja schon. > > Dann mach das doch ganz einfach über eine Präprozessoranweisung, anstatt > so etwas kompliziertes wie eine Methodenpointer, der später alle anderen > eher verwirrt. So wird das in den bisherigen Bibliotheken gemacht, erfordert dann aber Eingriffe in die Bibliothek, um die #defines anzupassen. Das hat dann den unerwünschten Effekt, daß man zu jedem Projekt eine neue Kopie der Bibliothek anlegen muß, da die nach der Änderung eben nur noch für diesen einen Fall genutzt werden kann. Hinzu kommt die Compiler-Magie, die den Programmcode so abändert, daß man die #define nicht ins Anwendungsprogramm verlagern kann, und die undurchsichtige Auswahl der tatsächlich benutzten Bibliotheks-Variante - was müßte da zur Klarstellung noch alles abgeändert werden? Das kann man jedenfalls keinem Arduino-Programmierer zumuten :-( Diese ganzen Einschränkungen sind mir im Laufe der letzten Wochen aufgefallen, in denen ich mich mit dieser Bibliothek befaßt habe. Aber nun sehe ich endlich den (hoffentlich) richtigen Tunnel am Ende des Lichts ;-) DoDi
[toc] | [prev] | [next] | [standalone]
| From | Marc Santhoff <m.santhoff@t-online.de> |
|---|---|
| Date | 2016-03-09 20:47 +0100 |
| Message-ID | <20160309204745.5f8e05a5@puma.das.netz> |
| In reply to | #203890 |
Hans-Peter Diettrich <DrDiettrich1@aol.com> schrieb: > Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, > von denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider > sind meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie > sich das mit einem Methoden-Pointer erledigen läßt :-( Nur mal eine allgemeine Anmerkung: Der ganze Kram funktioniert größtenteils exakt so, wie in Object Pascal. VMT, abstrakte und virtuelle Methoden, Klassendeklarationen, etc. Nur, daß eben eine andere Syntax benutzt wird. Marc -- Rot ist negativ, blau ist positiv.
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-09 22:33 +0100 |
| Message-ID | <dkbj5uFtl63U2@mid.individual.net> |
| In reply to | #203910 |
Marc Santhoff schrieb: > Der ganze Kram funktioniert größtenteils exakt so, wie in Object > Pascal. VMT, abstrakte und virtuelle Methoden, Klassendeklarationen, > etc. Nur, daß eben eine andere Syntax benutzt wird. Und genau diese andere Syntax wüßte ich gerne. DoDi
[toc] | [prev] | [next] | [standalone]
| From | Christian Zietz <newsgroup.1001@chz.xyz> |
|---|---|
| Date | 2016-03-09 23:11 +0100 |
| Message-ID | <dkblc7Fu616U1@mid.individual.net> |
| In reply to | #203921 |
Hans-Peter Diettrich schrieb: > Und genau diese andere Syntax wüßte ich gerne. In der schon geposteten FAQ beschrieben. Christian -- Christian Zietz - CHZ-Soft - czietz (at) gmx.net WWW: http://www.chzsoft.de/ PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA
[toc] | [prev] | [next] | [standalone]
| From | Marc Santhoff <m.santhoff@t-online.de> |
|---|---|
| Date | 2016-03-10 01:29 +0100 |
| Message-ID | <20160310012927.5aca068e@puma.das.netz> |
| In reply to | #203921 |
Hans-Peter Diettrich <DrDiettrich1@aol.com> schrieb: > Marc Santhoff schrieb: > > > Der ganze Kram funktioniert größtenteils exakt so, wie in Object > > Pascal. VMT, abstrakte und virtuelle Methoden, Klassendeklarationen, > > etc. Nur, daß eben eine andere Syntax benutzt wird. > > Und genau diese andere Syntax wüßte ich gerne. Zu Pointer und Funktionen: http://www.newty.de/fpt/index.html Für's Grundlegende zum Auffrischen: http://www.bg.bib.de/FHDW/Intranet/prg/docs/CPPkompakt.pdf Mein PDF hatte zwar eine total verfusselte Seitennummerierung, war aber gut lesbar und verständlich. Marc
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-11 13:24 +0100 |
| Message-ID | <dkfrogFgl9sU1@mid.individual.net> |
| In reply to | #203944 |
Marc Santhoff schrieb: > Hans-Peter Diettrich <DrDiettrich1@aol.com> schrieb: > >> Marc Santhoff schrieb: >> >>> Der ganze Kram funktioniert größtenteils exakt so, wie in Object >>> Pascal. VMT, abstrakte und virtuelle Methoden, Klassendeklarationen, >>> etc. Nur, daß eben eine andere Syntax benutzt wird. >> Und genau diese andere Syntax wüßte ich gerne. > > Zu Pointer und Funktionen: > > http://www.newty.de/fpt/index.html Danke :-) Es wurden da zwar nicht alle meine Fragen beantwortet, aber hilfreich war es doch. Nach einigen Versuchen kann ich nur unterstreichen, daß man tunlichst ein typedef verwenden sollte! Die neue Bibliothek erzeugt grade mal 20 Bytes mehr Code, wovon 8 Byte auf eine Dummy-Funktion (zur Vermeidung von NULL Pointern) entfallen :-) Jetzt muß ich noch die Kompatibilität testen, und die mitgelieferten Beispiele anpassen. > Für's Grundlegende zum Auffrischen: > > http://www.bg.bib.de/FHDW/Intranet/prg/docs/CPPkompakt.pdf > > Mein PDF hatte zwar eine total verfusselte Seitennummerierung, war aber > gut lesbar und verständlich. Die Seitennummern sind tatsächlich sehr seltsam. Ansonsten sieht es gut aus. DoDi
[toc] | [prev] | [next] | [standalone]
| From | Edzard Egberts <ed_09@tantec.de> |
|---|---|
| Date | 2016-03-10 08:51 +0100 |
| Message-ID | <nbr91m$rv5$1@news.albasani.net> |
| In reply to | #203890 |
Hans-Peter Diettrich wrote:
> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
> mit einem Methoden-Pointer erledigen läßt :-(
> (Singleton)
Ein Singleton kann eigentlich komplett statisch sein, so dass Du die
einfacheren C-Funktionspointer verwenden kannst, indem Du die Methoden
static definierst und ggf. einen this-Pointer auf Deine Instanz übergibst:
class IRrecv;
typedef bool (foo_decode)(IRrecv* pThis);
class IRrecv {
public:
static bool decodeNEC(IRrecv* pThis);
static bool decodeSony(IRrecv* pThis);
char read(foo_decode pFoo); //soll intern Decoder aufrufen
};
char IRrecv::read(foo_decode pFoo) {
if (pFoo(this)) //??? soll die Methode aufrufen
return 'r';
else
return '?';
}
int main()
{
IRrecv irrecv;
irrecv.read(IRrecv::decodeNEC);
Die Dekoder-Funktionen müssen dann noch nicht einmal Methoden sein,
sondern können extern definiert werden. Die Klasse könnte man so auf ein
Datenobjekt beschränken, das die Parameter für die Dekoder enthält.
Eine echte C++-Lösung wäre dagegen die Verwendung eines Interface, mit
dem sich die Funktionen als Objekt handhaben lassen:
struct i_decode
{ // Definition des Interface
virtual ~i_decode() {} // verhindert Compilerwarnung
virtual bool decode()= 0; // Deklaration Funktionsaufruf
};
struct f_decode_NEC: public i_decode
{ // Definition eines Dekoders, beachte Vererbung vom Interface
virtual ~f_decode_NEC() {} // verhindert Compilerwarnung
virtual bool decode() { return true; } // Definition Funktion
};
struct f_decode_Ed: public i_decode
{ // Definition noch eines Dekoders
virtual ~f_decode_Ed() {} // verhindert Compilerwarnung
virtual bool decode() { return false; }
};
Verwendung mit Aufruf über die Basisklasse:
i_decode* pFoo= new f_decode_NEC; // Funktionsobjekt anlegen
if (pFoo->decode()) do_anything(); // benutzt decode_NEC
oder statisch:
f_decode_NEC DNC; // Funktionsobjekt anlegen
i_decode* pFoo= &DNC; // Dem Zeiger zuweisen
if (pFoo->decode()) do_anything(); // ausführen
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com> |
|---|---|
| Date | 2016-03-10 16:33 +0100 |
| Message-ID | <dkdk1sFemhsU1@mid.individual.net> |
| In reply to | #203959 |
Edzard Egberts schrieb:
> Hans-Peter Diettrich wrote:
>> Problem: eine Klasse implementiert mehrere (gleichartige) Methoden, von
>> denen eine bestimmte zur Laufzeit aufgerufen werden soll. Leider sind
>> meine C++ Kenntnisse sehr angestaubt, ich komme nicht drauf wie sich das
>> mit einem Methoden-Pointer erledigen läßt :-(
>> (Singleton)
>
> Ein Singleton kann eigentlich komplett statisch sein, so dass Du die
> einfacheren C-Funktionspointer verwenden kannst, indem Du die Methoden
> static definierst und ggf. einen this-Pointer auf Deine Instanz übergibst:
In diesem Fall würde ich die Instanz ganz wegoptimieren. Bislang werden
die zugehörigen Daten in 3 Strukturen gespeichert, eine statische für
den Interrupt-Handler, eine für das dekodierte Ergebnis (Parameter), und
dann noch die Klasse selbst. Das Ergebnis habe ich momentan bereits in
die Klasse integriert, es könnte aber auch komplett global werden und
auch die Elemente der Klasse enthalten.
[...]
> int main()
> {
> IRrecv irrecv;
> irrecv.read(IRrecv::decodeNEC);
Hier stört mich noch der aufwendige Parameter (Tippfehler!), dafür
sollte ich wohl noch Makros definieren.
> Die Dekoder-Funktionen müssen dann noch nicht einmal Methoden sein,
> sondern können extern definiert werden. Die Klasse könnte man so auf ein
> Datenobjekt beschränken, das die Parameter für die Dekoder enthält.
Das war auch meine erste Idee. Doch dann habe ich mich für die
Beibehaltung der Klasse entschieden, mit den Standard-Methoden begin(),
available() und read(), die jeder Arduino Programmierer von den anderen
Stream-Klassen gewohnt ist.
> Eine echte C++-Lösung wäre dagegen die Verwendung eines Interface, mit
> dem sich die Funktionen als Objekt handhaben lassen:
Dagegen spricht die universelle decode() Methode, die alle verfügbaren
Dekoder durchprobiert, und die weiterhin nutzbar sein sollte. Die müßte
dann auf Instanzen aller abgeleiteten Klassen zugreifen, mit höherem
Speicherbedarf (zumindest bei den VMT).
Vielen Dank für die ausführlichen Codechnipsel :-)
Zumindest weiß ich jetzt, was für eine Sorte Pointer ich brauche, und
hoffe, daß ich nun auch die Lücken im ursprünglichen Beitrag richtig
füllen kann.
DoDi
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | de.sci.electronics
csiph-web