UNion?Wie und warum?FUnktionspointer?Wie und warum?
-
Hi leute, habe mich von dem Thread mit ähnlichem name inspirieren lassen!
Also meine Fragen: wozu braucht man Unions?
Ich weiß wie man es schreibt....aber ich weiß nich unbedingt wo ich eins wirkl brauche!Und für was brauch ich FUnktions-bzw Methodenzeiger??
würde mich über eine erklärung freuen (vielleicht auch ein praktisches beispiel)!
-
Funktionszeiger könnte man z.B. für ne Messaagequeue verwenden. Wenn ein Objekt ne Message bekommt ruft es einfach den Funktionspointer auf und übergibt sich als Argument.
-
Klassenfrage schrieb:
Also meine Fragen: wozu braucht man Unions?
z.b. um speicher zu sparen. alle union-members belegen den gleichen platz, wenn du was reinschreibst veränderst du alles
-
Klassenfrage schrieb:
Also meine Fragen: wozu braucht man Unions?
Ich weiß wie man es schreibt....aber ich weiß nich unbedingt wo ich eins wirkl brauche!union ipaddress{ struct { char a,b,c,d;//oder d,c,b,a? } long l; };
für sonst nix. man kann stets auch hart casten, statt unions zu benutzen. da man kaum sachen mit konstruktoren oder destruktoren sinnvoll in unions stecken kann, sind sie akut vom aussterben bedroht.
Und für was brauch ich FUnktions-bzw Methodenzeiger??
methodenzeiger sind wie gesagt für message-queues ne tolle sache.
funktionszeiger sind eigentlich auch tot. man schreibt heute funktionsobjekte. manchmal kann es eine tick performancxe bringen, funktionszeiger zu benutzen statt funktionsobjekten mit virtueller methode.
-
Also in c++ kriegen Funktionszeiger echt durch Funktoren kokurenz, ist aber das gleiche Kozept prinzipiell: man will oder kann erst zur Laufzeit entscheiden, welche Funktion aufgerufen wird.
Mit unions kann man einerseits so spielereien wie wie 4*char nach int oder so machen:union cool_caster { __int64 i; struct { char c1; char c2; char c3; char c4; }chars; };
Andererseits wurden sie natürlich nicht deswegen erfunden. Sie sind eine alte Kriegswaffe aus C zeiten, um nicht zuviel Speicherplatz zu vergeuden, ein beispiel aus dem Linuxkernel (seehr aus dem Degächtnis):
struct inode { //daten halt union { minix_spezifische Struktur; ext2_spezifische Struktur; //... void *generischer_speicherplatz; }; };
Is jetzt natürlich mehr oder weniger Pseudocode, warte ich suchs mal raus: ah, sehe grad, wird nurnoch void* benutzt, aber egal...
-
aha, also kann ich eigentlich unions und funktionszeiger vergessen oder wie?
2 bitten noch:
Könnte mir jemand mal ein FUnktionsobjekt oder FUnktor zeigen?
GLeiches gilt für MEssage-queues(wasn das eigentlich? //hab ich noch nie was von gehört
-
Naja, in manchen situationen kann man sie schon benutzen, aber sie haben viel von ihrer mächtigkeit eingebüßt.
//funktor - Objekt mit überladenem operator(...) class abstr_ftor { public: virtual void operator()(abstr_obj&)const; //abstr_obj woanders definiert... }; class example_ftor1 :public abstr_ftor { public: void operator()(abstr_obj& ao)const { //... }; }; class example_ftor2 :public abstr_ftor { public: void operator()(abstr_obj& ao)const { //... }; }; class message_queue { private: std::list<std::pair<abstr_object&,const abstr_ftor&> > objs; public: void add(abstr_obj& o,const abstr_ftor& f { objs.push_back(std::pair<abstr_object&,const abstr_ftor&>(o,f)); }; void call() { std::list<std::pair<abstr_object&,const abstr_ftor&> >::iterator begin(objs.begin()),end(objs.end()); for(;begin!=end,++begin) begin->second(begin->first); //Aufruf des Funktors }; //... };
-
Mit unions kann man einerseits so spielereien wie wie 4*char nach int oder so machen
Nein kann man nicht.
man kann stets auch hart casten, statt unions zu benutzen
Nicht auch. Man kann unions überhaupt nicht zum casten benutzen.
Man darf bei Unions immer nur das zuletzt geschriebene Element lesen.
Alles andere führt zu undefiniertem Verhalten. Es gibt da natürlich eine Ausnahme, aber die ist in diesem Thread eigentlich nicht relevant.Unions sind dazu da, Platz zu sparen, wenn man optionale Member hat von denen zu jedem Zeitpunkt aber immer nur ein Member relevant ist. Ein bekanntes Beispiel ist eine Stringklassen mit "small string optimization".
Wer bereit ist in solchen Situationen die paar Extrabytes zu zahlen braucht keine unions (der Normalfall).
aha, also kann ich eigentlich unions und funktionszeiger vergessen oder wie?
Nö. Die Tatsache dass es Alternativen gibt heißt nicht automatisch, dass man alles andere vergessen kann. Die Kunst beim Programmieren ist es aus der Menge der vielen Möglichkeiten die man hat, die für die Situation am Besten passende auszuwählen.
-
Klassenfrage schrieb:
aha, also kann ich eigentlich unions und funktionszeiger vergessen oder wie?
unions kann man getrost vergessen. und funktionszeiger schiebt man sich am besten so lange auf, bis man sie mal aus versehen kapiert hat.
Könnte mir jemand mal ein FUnktionsobjekt oder FUnktor zeigen?
//wer sieht in diesem code was komisches? struct Plutimizierer{ double f; Plutimizierer(double _f){ f=_f; } double rechne(double x)( return x*f; } };
Und verwenden tut man sowas am liebsten mit templates
//wer sieht in diesem code was komisches? template<typename F> void test(F const& f){ for(double i=0;i<2;i+=0.1) cout<<i<<\t\<<f.rechne(i)<<endl; } ... Plutimizierer verdoppler(2); test(verdoppler);
GLeiches gilt für MEssage-queues(wasn das eigentlich? //hab ich noch nie was von gehört
hab keinen code. sind einfach warteschlangen, in die man nachrichten reintut. nachrichten an objekte sind eigentlich methodenaufrufe. statt in die queue zahlen zu tun wie 0,1,2,3 oder enums wie OPEN,CLOSE,WAIT,IDLE kann man auch gleich zeiger auf die methoden open(),close(),wait(),idle() reintun. das spart dann einen switch im dispatcher, den man bauen müßte, um die enums in eigene methodenaufrufe umzusetzen.
und zum komischen von oben
struct
class ist angemessener. zum einen kann man dann zur sicherheit das attribut dicht machen, zum anderen sind structs mit methoden recht unüblich.
Plutimizierer
gut versteckter rechtschreibfehler. es müßte Multiplizierer heißen.
{ double f;
private wäre fein gewesen.
Plutimizierer(double _f){ f=_f; }
Initialisiererliste, um konsistent mit anderem code zu sein, wo sie einfach nötig ist.
double rechne(double x)(
return x*f;
}}
den op() überladen wäre netter.; template<typename F> void test(F const& f){
ausnahmsweise mal nix zu meckern. ich hab bestimmt was übersehen.
for(double i=0;i<2;i+=0.1)
haha! total krankes verhalten. läuft die schleife bis 2 dann hört sie VOR 2 auf, läuft sie bis 3, dann hört sie NACH der 3 auf.
cout<<i<<\t\<<f.rechne(i)<<endl;
eigentlich sollten wir '\n' statt endl nehmen.
Plutimizierer verdoppler(2); test(verdoppler);
nutzlose temp-variable. dazu wurd doch const& in test übernommen.
-
hehe @ volkard: das nebenbei erzählte tutorial (find ich aber geil)
WOBEi ich nicht alles verstanden habe was hier erzählt wurde!
Also vergess ich unions, und fkt zeiger heb ich mir erstmal auf ;)!Die anderen sachen muss ich mir nochmal genauer anschauen!...DANKE
-
volkard schrieb:
//wer sieht in diesem code was komisches? // ICH, ICH *aufzeig* struct Plutimizierer{ double f; Plutimizierer(double _f){ f=_f; } double rechne(double x)( // <-- müste eine { sein statt der ( sein *g* return x*f; } };
ansonsten ist kein Fehler, da man seine struct-uren so nennen kann wie man will
P.S: Don sei mir bitte bitte nicht pöse (wer sieht hier was komisches?)
-
cout<<i<<\t\<<f.rechne(i)<<endl;
eigentlich sollten wir '\n' statt endl nehmen.
warum?
-
Woems schrieb:
P.S: Don sei mir bitte bitte nicht pöse (wer sieht hier was komisches?)
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
-
net schrieb:
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
?
-
volkard schrieb:
net schrieb:
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
?
täusche ich mich da? glaube, sowas mal wo gelesen zu haben.
-
volkard schrieb:
net schrieb:
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
?
Nur im globalen Namensraum sowie im Namensraum std.
Folgt auf den Unterstrich ein Großbuchstabe, so ist der Name generell reserviert.
-
net schrieb:
Woems schrieb:
P.S: Don sei mir bitte bitte nicht pöse (wer sieht hier was komisches?)
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
-
net schrieb:
Woems schrieb:
P.S: Don sei mir bitte bitte nicht pöse (wer sieht hier was komisches?)
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
in deinem geQuoteten Text, sehe ich nur 1 Fehler und der ist pöse.
Du hast zwar den richtigen Teil geQuotet, aber leider den falschen Fehler gefunden :p , in einem Teil den ich geQuotet habe
. Wenn das mal nicht verwirrt.
volkard schrieb:
net schrieb:
z.b. namen die mit underscores anfangen sollte man nicht verwenden. die sind reserviert für compiler-eigene variablen, konstanten usw.
?
ganz meiner meinung, direkt am Thema vorbei
aber nun zurück zum Thema:
Klassenfrage schrieb:
hehe @ volkard: das nebenbei erzählte tutorial (find ich aber geil)
[...]
DANKEstimmt, das "nebenbei" Tutorial ist echt spitze, gut erklärt!
-
Btw....kann das auch nicht Multiplizierer heißen, DENN
volkard schrieb:
struct Plutimizierer{
double f;
Plutimizierer(double _f){
f=_f;
}
double rechne(double x)(
return x*f;
}
};wo isn das 2te l?
Multiplizierer