Verleitet C++ zum komplizierteren denken?
-
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
-
u_ser-l schrieb:
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
Wieder ein Versuch, mich zu veralbern. Aber der ist doch längst schon vorweggenommen.
u_ser-l schrieb:
volkard schrieb:
volkard schrieb:
Die Hashtable ist natürlich nicht ein Array von Zeilen-Hashtables, sondern Zeilen- und Spaltenindex werden zum hashkey kombiniert.das ändert am Prinzip gar nichts.
Anscheinend doch.
Lies auch double dispatching in smalltalk:
http://www.mimuw.edu.pl/~sl/teaching/00_01/Delfin_EC/Patterns/DoubleDispatch.htm
-
abc.w schrieb:
Aber sagt MISRA einem PC Programmierer überhaupt was?
MISRA erinnert mich an "miserabel"
Aber das ist doch so ein Fahrzeug/Auto C Standard, oder? Irgendwo mal gehört, war glaub ich in irgendeiner Vorlesung.Grüssli
-
u_ser-l schrieb:
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
Ich frag mich gerade, was an diese Struktur objektprogrammiert sein soll o_O vielleicht liegt es ja nur an meine nicht vorhanden Wissen über Smalltalk.
-
volkard schrieb:
das return; kann ich mir für C noch vorstellen, ist bei C++ aber extrem schwachsinnig - gilt das auch für C++?
Habe gerade die Meldungen eines QAC++ Checker durchsucht, keine passende Regel gefunden, wahrscheinlich doch schwachsinnig für C++...
Dravere schrieb:
Aber das ist doch so ein Fahrzeug/Auto C Standard, oder?
Ja, so ungefähr, eher eine Zusammenstellung von Regeln. MISRA ist halb so schlimm, schlimm sind die Mitarbeiter (Vorgesetzten) die die Regeln für ein Projekt zusammenstellen
-
abc.w schrieb:
volkard schrieb:
das return; kann ich mir für C noch vorstellen, ist bei C++ aber extrem schwachsinnig - gilt das auch für C++?
Habe gerade die Meldungen eines QAC++ Checker durchsucht, keine passende Regel gefunden, wahrscheinlich doch schwachsinnig für C++...
Na, sauber. Ich nehme an, für C unterstützt dieser Zwang das Single-Exit-Konzept, was Ressourcenlöcher vermeidet. Man hat irgendwie Lust, das return da unten zu bevorzugen, wo es doch eh schon da steht.
-
um das dispatching Argument zu widerlegen, paßt es. Smalltalk rocks.
-
abc.w schrieb:
...noch gibt es MISRA Regeln und diese schreiben es so vor. Finde ich gut. Genauso wie ein return; bei void Funktionen:
das 'void' schreibe ich in C auch immer hin. mir fällts sogar auf, wenn's fehlt. aber ein return am ende einer void-funktion ist doch blöd. was soll das?
abc.w schrieb:
Aber sagt MISRA einem PC Programmierer überhaupt was?
bestimmt nicht. pc-progger haben echt glück, dass sie sich damit nicht belasten müssen. aber es gibt sicherlich noch viele andere furchtbare coding-richtlinien (hab mal was vom rüstungskonzern lockhheed für c++ gesehen). machmal ist sowas ja auch sinnvoll, denn schliesslich sind nicht alle programmierer so schlau wie volkard. und wenn irgendwo c++ in grossen projekten verwendet wird, geht's auch garnicht ohne sehr restriktive coding-styles, sonst kommen nur kraut und rüben raus.
abc.w schrieb:
Nur aus Neugier, benutzt jemand (freiwillig oder weil er muss) in seinen Projekten irgendwelche QAC/QAC++ Checker?
ich hab diverse toolchains die auch 'nen misra-checker drin haben, den lass ich zum spass mal durchlaufen um mir hunderte von regelverstössen vorwerfen zu lassen. ne, aber im ernst: ich benutze ziemlich oft das: http://www.splint.org/ das ist richtig gut.
-
u_ser-l schrieb:
Smalltalk rocks.
so toll smalltalk auch sein mag, aber ich finde die syntax absolut gruselig.
-
/fricky schrieb:
u_ser-l schrieb:
Smalltalk rocks.
so toll smalltalk auch sein mag, aber ich finde die syntax absolut gruselig.
Ich kann ihr einiges abgewinnen, weil sie so angenehm klein ist.
-
u_ser-l schrieb:
um das dispatching Argument zu widerlegen, paßt es.
Offensichtlich nicht.
Nochmal was zum Lernen: http://dixie.cs.uiuc.edu/cs598rej/uploads/87/double-dispatch.pdf
Deine Logik liegt in einer mir fremden Zonentaxonomie, fürchte ich.
-
-
~john schrieb:
Da wird nicht simuliert! Es ist echtes OOP! Einiges wird in C++ nicht direkt unterstützt, aber das trifft etwa auch auf Smalltalk zu.
Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:
#include<iostream> using namespace std; class A { private: char c; public: A() { c = 'a'; } char* get() { return &c; } }; int main(){ A a; cout << "private a.c ist '" << *a.get() << "'" << endl; *a.get() = 'b'; cout << "und jetzt: '" << *a.get() << "'" << endl; }
der Kompeiler g++ -Wall
spuckt bei mir übrigens nicht einmal eine warning aus, obwohl im Manual zu lesen ist:
(Zitat)-Wall This enables all the warnings about constructions that some users consider questionable, [...]
- es ist demzufolge not questionable, private members eines Objektes unbefugt von außen zu ändern :p
-
und hier kann ich die private Innerei des Objekts b der Klasse B manipulieren, indem ich einen Zeiger benutze, der vom Objekt a der Klasse A stammt - das könnte allerdings plattform- oder implementationsabhängig sein:
#include<iostream> using namespace std; class A { private: char c; public: A() { c = 'a'; } char* get() { return &c; } }; class B { private: char c; public: B() { c = 'b'; } char get() { return c; } }; int main(){ B b; A a; cout << "private b.c ist '" << b.get() << "'" << endl; *(a.get() + 1) = 'x'; cout << "und jetzt: '" << b.get() << "'" << endl; }
Ausgabe bei mir:
private b.c ist 'b' und jetzt: 'x'
-
u_ser-l schrieb:
- es ist demzufolge not questionable, private members eines Objektes unbefugt von außen zu ändern :p
Es gibt Tools zur statischen Analyse des Quellcodes und Fehler dieser Art (ich nenne sie jetzt einfach mal Fehler, obwohl der Compiler nicht mal eine Warnung ausspuckt) würden sofort auffallen
-
u_ser-l schrieb:
~john schrieb:
Da wird nicht simuliert! Es ist echtes OOP! Einiges wird in C++ nicht direkt unterstützt, aber das trifft etwa auch auf Smalltalk zu.
Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:
#include<iostream> using namespace std; class A { private: char c; public: A() { c = 'a'; } char* get() { return &c; } }; int main(){ A a; cout << "private a.c ist '" << *a.get() << "'" << endl; *a.get() = 'b'; cout << "und jetzt: '" << *a.get() << "'" << endl; }
Es wird gekapselt, aber was anderes, naemlich der Pointer (die Adresse) und nicht der Wert auf den der Pointer zeigt. Wuerde sowas z.B. funktionieren, dann wuerde die Kapselung verletzt werden:
a.get() = 0xFF00FF; // irgendeine Adresse
In C++ gibt es aber trotzdem keine Kapselung im OOP-Stil, weil alle private member der Klasse oeffentlich bekannt sind und jede Aenderung an den private members eine Aenderung des Client-Codes noetig macht (man muss den Client-Code neu uebersetzen).
-
und hier ein Objekt, auf das man nach Zerstörung munter zugreifen kann:
#include<iostream> using namespace std; class A { private: char *s; public: A() { s = (char*)"bin noch da!"; } ~A() { cout << "Destruktor (und weg)" << endl; } char *get() { return s; } }; int main(){ A a; a.~A(); cout << a.get() << endl; a.~A(); cout << a.get() << endl; }
Ausgabe bei mir:
Destruktor (und weg) bin noch da! Destruktor (und weg) bin noch da! Destruktor (und weg)
und auch keine warning bei g++ -Wall ...
echte OOP oder namespace feature ?
-
Offen gesagt sehe ich nicht den Zusammenhang zwischen den zweifelsohne zahllosen Fällen, in denen C++ groben Unfug zu betreiben erleichtert oder überhaupt erst ermöglicht, und der objektorientierten Programmierung.
Davon abgesehen sind deine Beispiele unsinnig. Wenn du ein Element hättest kapseln wollen, hättest du einen const-Verweis zurückgegeben. Und der zweite Fall ist einfach falsch - worauf dich z.B. CodeGuard hingewiesen hätte. Es hindert dich ja auch in Java oder C# niemand daran, dispose() mehrfach oder finalize() explizit aufzurufen.
-
Ich finde nicht dass C++ zu komplizietem Denken vereleitet. Ich programmiere seit etwa 5 Jahren in C++. Das wäre mir aufgefallen
-
Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:
es gibt einen Unterschied zwischen Unterstützen und Erzwingen.
In C++ gibt es aber trotzdem keine Kapselung im OOP-Stil, weil alle private member der Klasse oeffentlich bekannt sind und jede Aenderung an den private members eine Aenderung des Client-Codes noetig macht (man muss den Client-Code neu uebersetzen).
Diese Aussage trifft nicht wirklich zu, weil der Client Code nicht geändert wird, sondern nur das Resultat. Aber ist das wirklich gegen OOP?