Forum: Compiler & IDEs C/C++ Objektmethoden


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Michael (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hallo zusammen

Beim Recherchieren für das Programmieren von Mikrocontrollern stosse ich 
immer wieder auf verschiedene Syntax, wenn es um den Aufruf von 
Objektmethoden geht.

Viele Beispiele zeigen folgendes:
1
Objekt.Methode();
manche aber:
1
Objekt->Methode();

Worin liegt hier der Unterschied?

: Verschoben durch Moderator
von Stefan ⛄ F. (stefanus)


Bewertung
2 lesenswert
nicht lesenswert
Das erste ruft die Methode einer Objektreferenz auf. Das andere ruft die 
Methode über einen Zeiger auf, der auf die Objektinstanz zeigt.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Das Ganze geht nur in C++, daher ist "C/C++" falsch. Außerdem heißt das 
nur in Java "Methode", in C++ heißt das "Member Funktion".

von Michael (Gast)


Bewertung
-13 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Das erste ruft die Methode einer Objektreferenz auf. Das andere ruft die
> Methode über einen Zeiger auf, der auf die Objektinstanz zeigt.

Stefan, bitte schreibe mir in diesem Thread nicht mehr weiter. Ich habe 
schon einige deiner Kommentare gelesen... Leider meist unverständlich 
und zu hochstehend - wie dieser hier. Nichts für ungut.

von N. G. (newgeneration) Benutzerseite


Bewertung
2 lesenswert
nicht lesenswert
Hallo,

ich denke das ganze wird klarer, wenn man sich Variablen anschaut:

Wir haben eine Struktur/Klasse S:
1
struct S {
2
    int x;
3
};
und legen von dieser eine Variable an:
1
S variable;
Nun kann man ganz normal mittels "Punkt" auf die Struct-Variable 
zugreifen:
1
variable.x = 42;

Nun haben wir aber irgenwie einen Zeiger auf diesen Struct (z.B. durch 
dynamischen Speicher oder durch einen Parameter):
1
S *pointer;
Bevor man auf die Member-Variable zugreifen kann muss man erst einmal 
dereferenzieren:
1
(*var2).x = 42;
Diese Schreibweise (also mit Klammern) ist wegen der 
Operator-Reihenfolge nötig, aber umständlich, deswegen gibt es auch den 
kürzeren "Pfeil":
1
var2->x = 42;
Das ganze funktioniert dann komplett analog dazu.

Mit freundlichen Grüßen,
N.G.

von Johann L. (gjlayde) Benutzerseite


Bewertung
4 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Das Ganze geht nur in C++, daher ist "C/C++" falsch.

Falsch, es geht auch in C:
1
void func (void) {}
2
3
typedef struct
4
{
5
    void (*Methode) (void);
6
} object_t;
7
8
void test (const object_t *Object)
9
{
10
    Object->Methode();
11
}
12
13
int main()
14
{
15
    object_t Object = { func };
16
    Object.Methode();
17
    test (&Object);
18
}

von Michael (Gast)


Bewertung
1 lesenswert
nicht lesenswert
N. G. schrieb:
> ich denke das ganze wird klarer, wenn man sich Variablen anschaut:

Hey, vielen Dank! Das hilft mir weiter.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Falsch, es geht auch in C:

Achja, das vergesse ich immer. Ist ja auch nicht genau das gleiche;-)

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Stefan, bitte schreibe mir in diesem Thread nicht mehr weiter. Ich habe
> schon einige deiner Kommentare gelesen... Leider meist unverständlich

Nicht jedem ist es gegeben, sich auf dein Niveau herunter zu denken.
Eventuell [1] liegt das Problem ja auf deiner Seite.


[1] das Wort steht da als Tribut an die Höflichkeit

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
N. G. schrieb:
...
> Nun haben wir aber irgenwie einen Zeiger auf diesen Struct (z.B. durch
> dynamischen Speicher oder durch einen Parameter):S *pointer;
> Bevor man auf die Member-Variable zugreifen kann muss man erst einmal
> dereferenzieren:(*var2).x = 42;

Das wäre deutlich klarer, wenn du nicht mitten drin den Namen der 
(Pointer-)Variablen ändern würdest. Also besser:
1
S *pointer;

und dann
1
(*pointer).x= 42;

bzw. als abgekürzte Schreibweise
1
pointer->x= 42;

von Johann L. (gjlayde) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Beim Recherchieren für das Programmieren von Mikrocontrollern stosse ich
> immer wieder auf verschiedene Syntax, wenn es um den Aufruf von
> Objektmethoden geht.
>
> Viele Beispiele zeigen folgendes:
>
> Objekt.Methode();
>
> manche aber:
>
> Objekt->Methode();
>
> Worin liegt hier der Unterschied?

...und für C++: Der Code ist 1. nicht Mikrocontroller-spezifisch und 2. 
sind die gegebenen Antworten in dem Sinne unvollständig, dass allein aus 
der Syntax nicht auf die Semantik der Code-Schnippel geschlossen werden 
kann. Insbesondere bedeuten weder "*Object" noch "Object->" dass 
"Object" ein Zeiger sein muss.

Daher kann
1
(*Object).Method();
etwas anderes sein als
1
Object->Method();

Beispiel:
1
struct B
2
{
3
  int value;
4
  B (int value) : value(-value) {}
5
  int Method () const
6
  {
7
    return 3 + value;
8
  }
9
};
10
11
struct A
12
{
13
  int value;
14
  A (int value) : value(value) {}
15
16
  B operator * () const
17
  {
18
    return B (value);
19
  }
20
  int Method() const
21
  {
22
    return value;
23
  }
24
  A* operator -> () const
25
  {
26
    return new A (2 + value);
27
  }
28
  
29
};
30
31
int testA1 (const A &Object)
32
{
33
  return Object.Method(); // Ok, return Object.value
34
}
35
36
int testA2 (const A &Object)
37
{
38
  return Object->Method(); // Ok, return 2 + Object.value
39
}
40
41
int testA3 (const A &Object)
42
{
43
  return (*Object).Method(); // Ok, return 3 - Object.value
44
}
45
46
int testA4 (const A *Object)
47
{
48
  return Object->Method(); // Ok, return Object.value
49
}

Sowohl prefix-* als auch -> können überladen werden, und ob das 
tatsächlich der Fall ist kann man nur wissen, wenn man die Definition 
von Object kennt.

Und Method braucht auch keine "Methode" zu sein, es kann eine Komponente 
sein, deren Klasse () überlädt.  Beispiel:
1
struct B
2
{
3
  int value;
4
  B (int value) : value(-value) {}
5
  int Method () const;
6
  int operator () () const
7
  {
8
    return 4 + value;
9
  }
10
};
11
12
struct A
13
{
14
  int value;
15
  B Method;
16
  A (int value) : value(value), Method(value) {}
17
18
  B operator * () const;
19
  A* operator -> () const;
20
};
In dem Falle hat man dann
1
int testA1 (const A &Object)
2
{
3
  return Object.Method(); // Ok, return 4 - Object.value
4
}
denn Object.Method liefert die Method-Komponente von A, welche vom Typ B 
ist, die wiederum () überlädt.

von Oliver S. (oliverso)


Bewertung
-1 lesenswert
nicht lesenswert
Und all die tollen Antworten nur, um die einzig zielführende Antwort zu 
vermeiden:

Nimm dein C/C++ Buch, und lies nach, was es mit den Operatoren und all 
dem anderen auf sich hat. Ohne Kenntnis der allereinfachsten und 
grundlegenden Konzepte und Syntax einer Programmiersprache versteht man 
Quelltexte nunmal nicht.

Ja, dieses Forum ist manchmal Anfängerfeindlich, und ja, das muß 
manchmal sein.

Oliver

von Alex G. (dragongamer)


Bewertung
0 lesenswert
nicht lesenswert
@gjlayde
Wah.. den () Operator zu überladen dürfte zu dem verwirrendsten Dingen 
gehören die man in C++ machen "kann"...

@oliverso
Da ist was dran. Die Geschichte mit den Pointern zählt allerdings klar 
zu dem an schwersten zu begreifenden Aspekten von C und C++. Besonders 
wenn man von höheren Sprachen kommt.
Dabei ist es weniegr das Konzept an sich von Speicheraddressierung 8was 
in Büchern auch breit und lang behandelt wird), sondern die Syntax 
selbst.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Alex G. schrieb:
> Die Geschichte mit den Pointern zählt allerdings klar zu dem an
> schwersten zu begreifenden Aspekten von C und C++.

Hab nie verstanden warum. Man muss sich nur überlegen wie so ein 
Speicher strukturiert ist... Und schwerer zu begreifen als z.B. 
Metaprogrammierung mit variadischen Templates usw?

Alex G. schrieb:
> Wah.. den () Operator zu überladen dürfte zu dem verwirrendsten Dingen
> gehören die man in C++ machen "kann"...

Ist aber absolut gängig, um Funktionale zu definieren. Mittlerweile dank 
Lambdas etwas weniger.

von Kaj G. (Firma: RUB) (bloody)


Bewertung
0 lesenswert
nicht lesenswert
Alex G. schrieb:
> Wah.. den () Operator zu überladen dürfte zu dem verwirrendsten Dingen
> gehören die man in C++ machen "kann"...
Schon mal einen ueberladenen []-Operator gesehen? Das ist nicht weniger 
verwirrend :D

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
> die man in C++ machen "kann"...

Gottseidank kann, nicht muss. Ich nutze dieses Feature nur sehr selten.

Wenn ich mir die ganzen langen und teils für mich verwirrenden Antworten 
anschaue, war meine erste Antwort wohl doch noch die Beste. Sie sollte 
nämlich nur die Stichworte nennen, mit denen man weiter suchen kann.

von Axel S. (a-za-z0-9)


Bewertung
1 lesenswert
nicht lesenswert
Alex G. schrieb:
> Wah.. den () Operator zu überladen dürfte zu dem verwirrendsten Dingen
> gehören die man in C++ machen "kann"...

Kommt darauf an, wofür man es verwendet. Es ist z.B. ein unheimlich 
schicker Weg, einem Container einen bounds-check zu verpassen.

> Die Geschichte mit den Pointern zählt allerdings klar
> zu dem an schwersten zu begreifenden Aspekten von C und C++

Du solltest hier C und C++ nicht in einen Topf werfen. In C++ braucht 
man an sehr vielen Stellen keinen Pointer, wo man in C einen braucht. 
Und zwar weil C++ call by reference kann und auch richtige Strings hat. 
Nackte Pointer sollte man in einem C++ Programm auch nicht verwenden 
(oder brauchen). Dynamische Allozierungen verpackt man besser in 
Objekten, dann kann man das Aufräumen auch gleich in den Destruktor 
legen. Wenn überhaupt noch Pointer auf der Anwendungsebene, dann 
Smartpointer.

von Alex G. (dragongamer)


Bewertung
0 lesenswert
nicht lesenswert
Da stimme ich Stefan mal in beiden Punkte zu...

Programmeire C++ allerdings nur für PCs. Eventuell hat man durch solche 
Konstrukte, Vorteile in Sachen Geschwindigkeit?


Dr. Sommer schrieb:
Und schwerer zu begreifen als z.B.
> Metaprogrammierung mit variadischen Templates usw?
Wenn man in die herantritt, hat man in der Regel schon einige Monate 
intensiver Erfahrung mit C++ und ist abgehärtet :D

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Gottseidank kann, nicht muss.

Und wie würdest du dann eine Prädikats-Funktion an std::find_if 
übergeben, die sich zusätzliche Dinge merkt? Mit Lambda's geht's 
mittlerweile kompakter, aber das ist auch nicht immer geeignet.

Kaj G. schrieb:
> Schon mal einen ueberladenen []-Operator gesehen? Das ist nicht weniger
> verwirrend :D
Ja, bei std::vector. Funktionier dann genau wie bei Arrays. Super 
kompliziert!

von Alex G. (dragongamer)


Bewertung
0 lesenswert
nicht lesenswert
Stimmt, Smartpointer nehmen einem inzwischen einiges ab.

von Arduino Fanboy D. (ufuf)


Bewertung
-2 lesenswert
nicht lesenswert
Überladene Operatoren sind sicher ein Schock, für Leute, welche aus 
einer Sprachecke kommen, welche das nicht kann.
(z.B. ich)

Aber mittlerweile habe ich sie lieben gelernt.

Zum Beispiel ermöglichen sie mir den "Datenfluss" zu betonen. Die 
Fixierung auf den Programmfluss spiegelt oftmals nicht das wieder, was 
man erreichen möchte.
Gerade, wenn man lang laufende Schleifen/Zeitabläufe aufreißen muss, um 
(quasi) Nebenläufigkeiten zu erreichen.

Hier ein Beispiel aus meiner Bastelstube, welches einfach nur 
Tastendrücke zählt.
1
void loop() 
2
{
3
  counter = flankenerkennung = entprellen = taster;
4
}

Wie gesagt, hier liegt die Betonung auf dem Datenfluss.
Der Programmfluss ist verborgen in den Klassen.
Auch die innere zeitliche Abfolge des entprellens ist unter dem Deckel.

: Bearbeitet durch User
von Stefan ⛄ F. (stefanus)


Bewertung
4 lesenswert
nicht lesenswert
> counter = flankenerkennung = entprellen = taster;

Oha, wie schrecklich!

> Überladene Operatoren sind sicher ein Schock, für Leute, welche aus
> einer Sprachecke kommen, welche das nicht kann.

Jawohl

von Alex G. (dragongamer)


Bewertung
1 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Wie gesagt, hier liegt die Betonung auf dem Datenfluss.
> Der Programmfluss ist verborgen in den Klassen.
> Auch die innere zeitliche Abfolge des entprellens ist unter dem Deckel.

Macht es dafür Sinn einen Operator so zweck zu entfremden?

Das problem ist eben, wenn jemand anders auf deinen Code da blickt, ohne 
diese Hintergründe zu kennen, dann denkt er erstmal "wieso werden da 
alle variablen auf den selben Wert gesetzt"?

Sieht sicherlich schön aus, aber wenn man nicht nur für sich selbst 
programmeirt, ist das eher ein graus.
Ich hätte für den Zweck eher versucht Java's "Streams" zu immitieren, 
damit es in etwa so aussieht:
1
counter = taster.entprellen().flankenerkennung().zaehlen();

Das wäre viel eindeutiger.

: Bearbeitet durch User
von Oliver S. (oliverso)


Bewertung
4 lesenswert
nicht lesenswert
Weil man alles kann (aber nicht muß), gibt’s ja inzwischen die C++ Core 
guidelines (denen man folgen kann, aber nicht muß) Und deren erste Regel 
zum Thema Operator-überladen lautet:

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ro-conventional

Der Zuweisungsoperator = sollte grundsätzlich und immer eine Zuweisung 
ausführen, in der Form, daß nach a=b a==b true liefert.

Alles andere ist nur was für den Confuscated C Contest.

Oliver

von Michael R. (fisa)


Bewertung
1 lesenswert
nicht lesenswert
Arduino F. schrieb:
> counter = flankenerkennung = entprellen = taster;

Das nennt man neudeutsch "job security" oder?

ungefähr genau so sinnvoll wie extensions.

von Arduino Fanboy D. (ufuf)


Bewertung
-2 lesenswert
nicht lesenswert
Nunja...
Muss ja keinem schmecken.

Gibt ja auch durchaus noch andere Notationen!
Meine Klassen sind in der Hinsicht recht vielgesichtig.

Alternative zu:
> counter = flankenerkennung = entprellen = taster;

Dies:
counter(flankenerkennung(entprellen(taster())));

Oder:
counter.doTrigger(flankenerkennung.doTrigger(entprellen.doTrigger(taster 
.isHigh())));

Alles das gleiche.
Frisst kein Byte mehr oder weniger.

von Alex G. (dragongamer)


Bewertung
2 lesenswert
nicht lesenswert
Es geht nicht um Bytes sondern um Leserlichkeit...

von Arduino Fanboy D. (ufuf)


Bewertung
-1 lesenswert
nicht lesenswert
Alex G. schrieb:
> Ich hätte für den Zweck eher versucht Java's "Streams" zu immitieren,
> damit es in etwa so aussieht:
> counter = taster.entprellen().flankenerkennung().zaehlen();

Da findet ein Fluss von links nach rechts statt. Es werden Referenzen 
übergeben.
Macht aus meiner Sicht keinen Sinn hier.
Ich möchte ja Zustände weiter reichen/zuweisen.

An anderer Stelle setze ich das gerne ein!
Auch dazu gerne ein Beispiel:
1
void setup() 
2
{
3
   Serial.begin(9600);
4
5
   adc  .enable()
6
        .setReference(Adc::REF_11)
7
        .setClockDivisor(Adc::DIV_128)
8
        .setSource(Adc::MUX_THERMO)
9
        .setCallBack(adcCallBack)
10
        .enableAutoTrigger()
11
        .setTrigger(Adc::TRIG_FREERUNNING)
12
        .enableIrq()
13
        .startConversion();
14
}

von Arduino Fanboy D. (ufuf)


Bewertung
-2 lesenswert
nicht lesenswert
Alex G. schrieb:
> Es geht nicht um Bytes sondern um Leserlichkeit...
Genau!
Und die erste Variante ist (für mich) leserlicher.
Verschachtlungen und Klammern zählen hasse ich wie die Pest.

Wenn man mal kapiert hat, worum es sich dreht, auch für andere.
(die Hoffnung stirbt zuletzt)

von Michael R. (fisa)


Bewertung
-1 lesenswert
nicht lesenswert
Alex G. schrieb:
> Es geht nicht um Bytes sondern um Leserlichkeit...

War das nicht eh der Knuth, der den Begriff des "literarischen 
Programmierens" geprägt hat?

muss wohl vor C++ gewesen sein ;-)

von Alex G. (dragongamer)


Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Alex G. schrieb:
>> Ich hätte für den Zweck eher versucht Java's "Streams" zu immitieren,
>> damit es in etwa so aussieht:
>> counter = taster.entprellen().flankenerkennung().zaehlen();
>
> Da findet ein Fluss von links nach rechts statt. Es werden Referenzen
> übergeben.
> Macht aus meiner Sicht keinen Sinn hier.
> Ich möchte ja Zustände weiter reichen/zuweisen.

Du hättest da durchaus den .-operator überladen können, wenn du keine 
Objektorientierung für diese kleine Sache willst, denn der 
offensichtliche Zweck des . - oeprators wäre gleich geblieben.
Beim Üebrladen von =, hast du den erheblich verändert.

Wieso ist das "Weiterreichen von Zuständen" denn deiner Meinung nach 
kein Fluss?

Du hast den Taster.
Der Taster wird entprellt.
Auf den entprellten Taster wird Flankenerkennung angewendet.
Die erkannten Flanken werden gezählt.

: Bearbeitet durch User
von Christopher J. (christopher_j23)


Bewertung
1 lesenswert
nicht lesenswert
Arduino F. schrieb:
> adc  .enable()
>         .setReference(Adc::REF_11)
>         .setClockDivisor(Adc::DIV_128)
>         .setSource(Adc::MUX_THERMO)
>         .setCallBack(adcCallBack)
>         .enableAutoTrigger()
>         .setTrigger(Adc::TRIG_FREERUNNING)
>         .enableIrq()
>         .startConversion();

Hier versteht jeder sofort was abgeht.



Arduino F. schrieb:
> counter = flankenerkennung = entprellen = taster;

und hier versteht (wenn überhaupt) nur derjenige der es geschrieben hat 
was abgeht. Bitte nimm es nicht persönlich aber ich sehe vor allem in 
der Arduino-Welt die kriminellsten Dinger wenn es um das überladen von 
Operatoren oder Funktionen geht. Das es funktioniert ist ja gar keine 
Frage aber der Code taugt dann nur noch für Obfuscation-Contests.

von Arduino Fanboy D. (ufuf)


Bewertung
-1 lesenswert
nicht lesenswert
Alex G. schrieb:
> Du hättest da durchaus den .-operator überladen können, wenn du keine
> Objektorientierung für diese kleine Sache willst, denn der
> offensichtliche Zweck des . - oeprators wäre gleich geblieben.
> Beim Üebrladen von =, hast du den erheblich verändert.


Da hätte ich doch mal gerne eine Vorführung gesehen!
Ein Beispiel.

Habe mir die überladbaren Operatoren ausführlich angesehen, aber der . 
ist mir dabei noch nicht unter gekommen.

http://en.cppreference.com/w/cpp/language/operators gibt das nicht her.
Und meine beiden C++ Bücher auch nicht.

Der Compiler schreit bei dem Versuch:
>  error: expected type-specifier before '.' token
ok, ok, da mag ich noch was falsch gemacht haben.

Was solls, ist ein Grund, nochmal auf die Suche zu gehen.....

---
2 Probleme sehe ich jetzt schon leuchten...

1. Bisher brauche ich für den Taster kein Byte Ram. Die definierte 
Instanz wird vollständig weg optimiert. Es bleibt nur die Inline 
Funktionalität im resultierenden Code erhalten. Ob mir das dann so 
erhalten bleibt? Wenn ich da mit Zeigern und Referenzen spielen muss?

2. Der Dot Operator würde mir die Initialisierung kaputt machen. 
taster.init(). Ohne Extrawürste wirds dann nicht gehen.

Wenn sich die beiden Sorgen ohne Probleme aushebeln lassen, wäre ich 
sehr erfreut. Muss es aber erst sehen und fühlen.

Ob ich
> counter = flankenerkennung = entprellen = taster
oder
> taster.entprellen.flankenerkennung.counter
schreibe ist mir echt egal...

: Bearbeitet durch User
von Alex G. (dragongamer)


Bewertung
0 lesenswert
nicht lesenswert
Oops, mein Fehler. Der Punkt ist tatsächlich eine Ausnahme.
Geht doch nicht alls in C++.

von Michael R. (fisa)


Bewertung
0 lesenswert
nicht lesenswert
ich würde den §-Operator vorschlagen ;-)

von Arduino Fanboy D. (ufuf)


Bewertung
0 lesenswert
nicht lesenswert
Alex G. schrieb:
> Oops, mein Fehler. Der Punkt ist tatsächlich eine Ausnahme.
> Geht doch nicht alls in C++.
Danke, für die Rückmeldung!

Und ich dachte schon...

Dann werde ich erstmal den Zuweisungsoperator beibehalten. Denn die 
anderen Operatoren sind noch "absurder" an der Stelle.

Werde dann warten, bis C++ mir den <- Operator erlaubt

counter<-flankenerkennung<-entprellen<-taster;

von Andreas M. (andiator)


Bewertung
2 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Werde dann warten, bis C++ mir den <- Operator erlaubt
>
> counter<-flankenerkennung<-entprellen<-taster;

Und warum nicht den Schiebeoperator '<<'? Würde sogar etwas Sinn 
ergeben.

MfG,
Andreas

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
> ich würde den §-Operator vorschlagen

Was macht man damit?

text=GrundGesetz§3.4;

> Und warum nicht den Schiebeoperator '<<'?

Das war auch mein spontaner Einfall dazu, schließlich wird der auch bei 
std::cout "missbraucht".

: Bearbeitet durch User
von Michael R. (fisa)


Bewertung
1 lesenswert
nicht lesenswert
Stefan U. schrieb:
>> ich würde den §-Operator vorschlagen
>
> Was macht man damit?
>
> text=GrundGesetz§3.4;

Die Leute in ihrem Bastelkeller einsperren, und nur ja nicht auf den 
Arbeitsmarkt lassen?

von Andreas M. (andiator)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
>
>> Und warum nicht den Schiebeoperator '<<'?
>
> Das war auch mein spontaner Einfall dazu, schließlich wird der auch bei
> std::cout "missbraucht".

Und auch in Qt-Containern:
1
QVector<QString> v;
2
v << "String 1";
3
v << "String 2";
4
v << "String 3" << "String 4" << "String 5";
5
6
// v[0] == "String 1",  v[1] == "String 2" usw.

MfG,
Andreas

: Bearbeitet durch User
von Arduino Fanboy D. (ufuf)


Bewertung
-2 lesenswert
nicht lesenswert
Andreas M. schrieb:
> Und warum nicht den Schiebeoperator '<<'? Würde sogar etwas Sinn
> ergeben.

Naja....

Habe ich drüber nachgedacht!
Und auch implementiert gehabt.

Würde dann im Extremfall zu so einem Bild führen:
1
void loop() 
2
{
3
 Serial << (counter << flankenerkennung << entprellen << taster) << endl;
4
}

Oder etwas klarer:
1
void loop() 
2
{
3
 counter << flankenerkennung << entprellen << taster;
4
 Serial << counter << endl;
5
}

Schien mir dann doch nicht angemessen zu sein.

: Bearbeitet durch User
von Vincent H. (vinci)


Bewertung
1 lesenswert
nicht lesenswert
Deine operator overloads verstoßen allesamt gegen das "principle of 
least astonishment".
https://en.wikipedia.org/wiki/Principle_of_least_astonishment

Für Außenstehende, für die deine Klassen alle eine Blackbox darstellen, 
ist in keinsterweiße nachvollziehbar was du mit dem assignment 
bezweckst.

von Fabian G. (kjion) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert

von Stefan ⛄ F. (stefanus)


Bewertung
-3 lesenswert
nicht lesenswert
Da widerspricht sich der Autor aber selbst mit seinem Beispiel:
1
Use an operator for an operation with its conventional meaning
2
3
std::cout << /* class members here */;

Schauen wir doch mal, wozu der << Operator spezifiziert ist:
1
Bitwise left shift  a << b
(https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B)

Da hat er die Ausnahme einfach zur Regel gemacht. Dumm gelaufen, würde 
ich mal sagen.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Deine operator overloads verstoßen allesamt gegen das "principle of
> least astonishment".

Was aber nichts daran ändert, dass man die Semantik der vom OP gezeigten 
2 Codezeilen nicht wissen kann, ohne die Definition der 
zugrundeliegenden Deklarationen und Definitionen zu kennen.

Ich würd auch jetzt nicht sagen, dass "->" zu überladen weniger oder 
mehr überraschend ist als die Default-Bedeutung von "->".

Dito für andere Features wie Ableitung etc.

: Bearbeitet durch User
von Stefan ⛄ F. (stefanus)


Bewertung
-1 lesenswert
nicht lesenswert
> Ich würd auch jetzt nicht sagen, dass "->" zu überladen weniger oder
> mehr überraschend ist als die Default-Bedeutung von "->".

Wohl wahr, einen Schönheitswettbewerb würde C++ nie gewinnen.

von Arduino Fanboy D. (ufuf)


Bewertung
-2 lesenswert
nicht lesenswert
Stefan U. schrieb:
> einen Schönheitswettbewerb würde C++ nie gewinnen.

Mir wäre ja auch Forth recht...
Aber das fühlt sich auf einer Von Neumann Maschine wohler.
Und irgendein Massenspeicher um das Image zu laden wäre auch schön.

Obwohl, einen "Schönheitswettbewerb" gewinnt man damit auch nicht.
Aber zumindest kann man sich da einen <- Operator bauen (ohne dass man 
erschlagen wird), wenn man meint einen zu brauchen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.