C++ Gurus



  • HumeSikkins schrieb:

    Was sicher ein wenig daran liegt, dass der Code aus dem Kontext gerissen ist.

    Klar, nur sehe ich halt den dennoch keinen Vorteil in einem H wenn man es auch Handle nennen kann... Und genau das habe ich gesagt: "ich verstehe es nicht". Wobei ich es auch lange so gemacht habe, aber wie ich mal darueber nachgedacht habe, habe ich festgestellt, dass es nur Bequemlichkeit ist.



  • verstehe die einstellung von HumeSikkins nicht. man sollte doch überall gut programmieren (wenn man es kann) und nicht nur nach aussen hin.



  • rasta schrieb:

    verstehe die einstellung von HumeSikkins nicht. man sollte doch überall gut programmieren (wenn man es kann) und nicht nur nach aussen hin.

    ja.

    aber nach innen gut und nach außen gut könne zweierlei dinge sein.

    ich stelle mir vor, ich mache gerade mit containern rum. mit hashtables mal. dann mit avl-trees. dann mit tries, dann mit ...
    alles auf der suche nach der geilsten datenstruktur, um ein gutes dictionary voller strings, wie sie in hochbelasteten nameservern so rumliegen, zu finen.

    da die gante zeit Key statt K und Value statt V zu schreiben, würde einen töen. wohlgemerkt, für eine dieser datenstrukturen, wenn sie zufriedenstellend sein soll, brauche ich mindestens 4 wochen.

    nun kann man sich auf den standpunkt stellen, daß man immer Key,Value schreiben sollte. den standpunkt halte ich für irrig.

    nun kann man sich auf den Standpunkt stellen, man sollte nach abschluß der forschungen K,V durch Key,Value ersetzen. geht ja mit search&replace der jeweiligen entwicklungsumgebung sehr gut. den standpunkt hielt ich für befremdlich. denn immerhin war *ich* ja nach solchen monaten sowas von im geschäft, daß ich mit den einbuchstabern weniger probleme hatte als mit langen bezeichnern.

    nun kann man sich auf den standpunkt stellen, man solle K,V lassen. (oder H,E). das habe ich bisher so gemacht. und es war nie ein problem. aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft (klar, nach 30 sekunden tröpfelt die erleuchtug ein, aber warum 30 sec dumm sein?). nun habe ich zu berfüchten, daß er meinen K,V-code genausoschlecht liest wie ich seinen H,E-code.

    ich schau mal. bin gerade heftig auf einem lokalen c++-vereinfachungs-kreuzzug und da fliegen auch ein paar templates und ein wenig metaprogrammierung vorbei. ich schau mal, wo ich einbuchstaber duldbar finde.

    übrigens waren zu anfang der template-benutzung einbuchstaber optimale bezeichner. man hatte ja nur mal T oder ganz selten noch nen zweiten buchstaben. da galt ungefär sowas

    erster buchstabe klein
     erstes wort ein verb im infinitiv
      ist eine funktion, die bool liefert
     erstes word ein verb in befehlsform
      ist eine funktion
     erstes wort ein nomen
      ist variable
    erstes wort gross
    [b] erstes wort einbuchstaber
      ist typ als templateparemater[/b] alle anderen buchstaben gross
      ist makro
     sonst
      ist klasse
    


  • aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft

    Und lag das wirklich an so Kleinigkeiten wie H und E oder vielmehr daran, dass der Code insgesamt nicht sonderlich klar ist und einige Basiskonzepte einfach schrecklich schlechte Namen haben?

    Ich hätte getippt, dass deine Schwierigkeiten an drei Dingen liegen:

    1. Der Code ist komplex, weil die Domäne komplex ist. Überlappende Events, verwaiste Handler usw. Da kommen viele Randfälle zusammen.

    2. Der Code ist komplex, da er bereits optimiert ist. Die "triviale" Implementation wäre deutlich einfacher, erzeugst dafür aber auch deutlich mehr Code (virtual function bloat -> type erasure).

    3. Der Code ist komplex, da einige Konzepte nicht gut benannt und nicht optimal orthogonal sind.

    Der dritte Punkt liegt eindeutig in meiner Unfähigkeit und Unerfahrenheit. Die relativ ausfürhliche Dokumentation (sowie die Tests) war dazu gedacht, über dieses Problem hinweg zu helfen.

    Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten. Warum? Ähnliche Implementationen von
    anerkannten C++ Experten sind imo nicht wirklich weniger komplex (zum Vergleich schaue man sich boost::signal oder aber Alexandrescus policy based observer an. Letztere ist in den zwei CUJ-Kolumnen
    "A policy based observer" beschrieben).

    PS: Falls jemand eine bessere Version hat, immer her damit.
    Muss aber die Anforderungen die ich beschrieben habe erfüllen. Also z.B. Typesafe und schneller als boost::signal sein.



  • nun habe ich zu berfüchten, daß er meinen K,V-code genausoschlecht liest wie ich seinen H,E-code.

    Ich habe von dir eine Version deiner Volkard-Lib. Da gibt es einige Sachen die ich nicht auf Anhieb verstehe. Das liegt aber weniger an den Namen in der Implementation oder an den verwendeten Sprachmitteln sondern vielmehr an der Theorie. Da muss ich mich halt mal eine Stunde hinsetzen, an meine Informatik-Ausbildung zurückdenken, ein- zwei Seiten im Sedgewick nochmal wiederholen und dann geht's auch.

    @Shade

    Klar, nur sehe ich halt den dennoch keinen Vorteil in einem H wenn man es auch Handle nennen kann

    Handle kann ich es z.B. nicht einfach nennen. Der VC 6.0 (der Compiler mit dem ich arbeite) hat die herrliche Angewohnheit zu sterben, wenn er über einen Template-Parameter stolpert, der den selben Namen wie eine normale Klasse hat.
    Und wenn ich die Wahl habe versaue ich mir lieber meine Template-Parameter als meine Klassen. Eine Klasse E wäre sicher schlimmer als ein Template-Parameter E.
    Bevor du jetzt antwortest: Natürlich ist das keine gültige Ausrede, da man den Parameter ja auch HandlerType oder DerTypDerDaWoSpaeterDurchEinHandlerErsetztWird nennen kann 😉



  • HumeSikkins schrieb:

    aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft

    Und lag das wirklich an so Kleinigkeiten wie H und E oder vielmehr daran, dass der Code insgesamt nicht sonderlich klar ist und einige Basiskonzepte einfach schrecklich schlechte Namen haben?

    ich hab nur das gepostete fragment angeschaut. dort sagten mir E und H erstmal wenig. recht schnell habe ich dann gerafft, daß E wohl Event und H wohl Handler heißen.

    HumeSikkins schrieb:

    Ich hätte getippt, dass deine Schwierigkeiten an drei Dingen liegen:
    1. Der Code ist komplex, weil die Domäne komplex ist. Überlappende Events, verwaiste Handler usw. Da kommen viele Randfälle zusammen.

    kann sein. domäne ist mir unbekannt.

    HumeSikkins schrieb:

    2. Der Code ist komplex, da er bereits optimiert ist. Die "triviale" Implementation wäre deutlich einfacher, erzeugst dafür aber auch deutlich mehr Code (virtual function bloat -> type erasure).

    jein. mit direktem code würde ich vielleicht das komzept eher sehen, mich dafür aber genausolange über ineffizienz wundern, wie ich vorher an überlegungszeit gespart habe. (also bei dir würde ich mich so lange wundern, weil ich von dir auch nur optimalen code zu sehen erwarte.)

    3. Der Code ist komplex, da einige Konzepte nicht gut benannt und nicht optimal orthogonal sind.

    das geht uns allen so. Shades angesprochene 30% der zeit, die er für's namensuchen verbraucht, sind wenig. für die benamsung brauche ich auch meistens nicht mehr. aber für die orthogonalität (und noch ein paar nettigkeiten) gehen zur zeit 99% drauf, seit monaten.

    Der dritte Punkt liegt eindeutig in meiner Unfähigkeit und Unerfahrenheit.

    in deiner domäne biste sicherlich erfahrener als alle hier. aber vielleicht mußte mal irgendwas praktisches wie einen guten http-server bauen, damit du objektiv erfahren bist (ok, dauert lange, aber es könnte den aufwand wert sein, insbesondere, um nicht dauerhaft in völlig irrelevantes abzuglitschen, manchmal frage ich mich nämlich, weshalb das fünfhundertachtunddreißigste entwurfsmuster implentiert und mit grußem bahnhof begrüßt wird, aber ich keinen kenne, der das benutzen mag, außer für eine demo).

    Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten.

    ich weiß nicht, was Schade macht. aber ich bin an ganz anderen problemen dran. mein projekt ist zur zeit "ich habe eine kernel.h und eine kernel.cpp, die mir triviale und elemetare sachen wie write() oder becomeIdleThread() zur verfügung stellen (so wenig wie möglich natürlich). und ich baue alles darauf auf, ich inkludiere außer in kernel.cpp keinen header mit <> drumherum. und ich achte auf einfachheit und kürze als ganz allerwichtigstes. zum beispiel habe ich das doofe problem gelöst, daß man nicht einen vector oder ein array mit 1000 ostreams anlegen kann. aber ich brauche das, also mache ich es. mit einem ArrayAllocator (der zählt einfach hoch) und placement new (op new(size_t,ArrayAllocator&). kennst ja meine abneigung gegen default-konstruktoren. jetzt darf ich sie ausleben. :D. naja, ich habe keine ahnung, ob der kram am ende gut wird. ich muss annehmen, dass die großen gurus meine allüren als kinderkrankheiten abgelegt haben. ist mir aber egal. ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es. solche versuche hab ich öfters gemacht, fast jährlich, aber so weit, wie heute, bin ich nie auch nur ansatzweise gekommen."



  • HumeSikkins schrieb:

    Ich habe von dir eine Version deiner Volkard-Lib.

    oh, gibt es sowas noch?
    schick sie mir mal volkard@normannia.de

    HumeSikkins schrieb:

    Und wenn ich die Wahl habe versaue ich mir lieber meine Template-Parameter als meine Klassen. Eine Klasse E wäre sicher schlimmer als ein Template-Parameter E.

    ich benutze gerade eine IDE (Code::Blocks), die auch bei template-paramtern so ein hilfe-fensterchen aufmacht und die möglichkeiten anzeigt.

    also ich tippe

    foo<
    

    und er schreibt

    foo<U,K,Y>
    

    haha.
    ist natürlich egal, weil ich foo kenne und selber gebaut habe oder das handbuch vorher gut gelesen habe, aber naja, vielleicht sollten wir in zukunft den template-parametern die gleiche achtung zollen wie normalen parametern.



  • HumeSikkins schrieb:

    Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten. Warum? Ähnliche Implementationen von
    anerkannten C++ Experten sind imo nicht wirklich weniger komplex

    Habe ich auch nie behauptet dass es unklar ist oder klarer geht. (btw, Guru bin ich auch nicht, ich schaue immer noch zu dir und volkard auf).

    Was mich aber beim ersten Blick verwirrt hat war ein H und ein Handler. Dass H fuer Handle oder Handler steht, ist in dem Zusammenhang genauso klar wie das E Event. Liegt aber wohl hauptsaechlich daran, dass Handler unguenstig gewaehlt wurde. Denn, soweit ich dass sehe, ist es nicht viel mehr als eine Verwaltung von Objekt und Methode. Und Handler ist gar sehr allgemein...

    Und da spiesst es sich IMHO. Du hast 2 Typen die Handler/Handle heissen... Das hat jetzt weniger mit dem H zu tun.

    PS: Falls jemand eine bessere Version hat, immer her damit.
    Muss aber die Anforderungen die ich beschrieben habe erfüllen. Also z.B. Typesafe und schneller als boost::signal sein.

    Der Code sieht IMHO ganz gut aus, die casts sind natuerlich ein Krampf, aber viel anders wird es nicht gehen...

    @volkard:
    taugt Code::Blocks denn mittlerweile etwas?



  • Ich möchte die Frage präzisieren. Beherrscht es einfaches Refactoring wie etwas umzubenennen oder Funktion extrahieren? Ich habe bisher noch keine IDE für C++ gesehen, die das kann. 😞

    volkard schrieb:

    ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es.

    Ui, das will ich auch. Das heißt, ich tue es, aber leider nicht, wenn ich was mit C++ mache. 😉 Was hast du dir da feines zusammengehackt?



  • Shade Of Mine schrieb:

    taugt Code::Blocks denn mittlerweile etwas?

    ich hab den debugger noch nicht ausprobiert (spricht für mich, oder?). und das hinzufügen von files ist einen oder zwei klicks zu umständlich. und ich hab nur console-anwendungen gebaut. sonst sind mir keine nachteile aufgefallen. aber einen riesigen vorteil hat sie: ich kann mein usiversal makefile drunter haben und Code::Blocks ruft einfach mein makefile auf.
    das universal makefile mußte übrigens zerstört und wiederaufgebaut werden

    # Volkards universal makefile
    # (c) 1999-2005 volkard@normannia.de
    # feel free to use it in any ways.
    
    CXXFLAGS:=-Wall -Werror -march=i586 -O3 -fno-rtti -pipe -s -DNDEBUG -DUNITTEST
    #CXXFLAGS:=-Wall -Werror -march=i586 -O3 -fno-rtti -pipe -s -DNDEBUG
    
    PROJECT:=$(basename $(notdir $(CURDIR)))
    TARGET_EXT:=
    ifeq ($(OS),Windows_NT)
     TARGET_EXT:=.exe
    endif
    TARGET:=$(PROJECT)$(TARGET_EXT)
    
    zip:=$(PROJECT).rar
    sources:=$(wildcard *.cpp)
    objects:=$(sources:.cpp=.o)
    deps:=$(sources:.cpp=.d)
    
    all:	$(TARGET)
    
    .PHONY:	all clean run zip
    
    $(TARGET):	$(objects) $(deps)
    	$(CXX) $(CXXFLAGS) -o $(TARGET) $(objects)
    
    -include $(deps)
    
    %.o %.d:	%.cpp makefile
    	$(CXX) $(CXXFLAGS) -MMD -c $<
    
    clean:
    	-$(RM) $(TARGET) $(objects) $(deps)
    
    run:	$(TARGET)
    	./$(TARGET)
    
    zip:
    	-$(RM) $(zip)
    	rar a -r -s -m5 -ap$(PROJECT) $(zip) *.cpp *.h makefile
    

    das alte war zu doof, die dependencies auch immer neu zu schreiben, weil sich eine *.h geändert hat, die in einer *.d afgelistet war. es waren die *.d nur von den *.cpp abhängig, was falsch ist. jetzt werden mit -MMD immer zur gleichen zeit eine *.o und eine *.d gebaut, womit auch garantiert ist, daß die *.d immer akltuell ist.



  • Optimizer schrieb:

    volkard schrieb:

    ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es.

    Ui, das will ich auch. Das heißt, ich tue es, aber leider nicht, wenn ich was mit C++ mache. 😉 Was hast du dir da feines zusammengehackt?

    das glaubste eh nicht, so einfach isses.
    ich hab übrigens den c++-standard verlassen und benutze hemmungslos typeof und auch die steuerung des alignments.

    #define each2(i,a) (typeof((a).begin()) i=(a).begin(),VHend=(a).end();i!=VHend;++i)
    //für for each(i,myVector)
    
    #define each3(i,a,b) (typeof(a) i=a,VHend=b;i!=VHend;++i)
    //für for each(i,0,100)
    

    ich muß leider each2 und each3 nehmen, weil ich keine möglichleit sah, für den MS-compiler beides eache heißen zu lassen (auf gcc kann ichs mit variadic macros.).



  • Optimizer schrieb:

    Ich möchte die Frage präzisieren. Beherrscht es einfaches Refactoring wie etwas umzubenennen oder Funktion extrahieren?

    äh. umbennenen macht man mit search&replace, oder? naja, man nennt es einfach um und fragt den compiler, wo's vorkommt, und macht die fehler alle raus. bin nir drauf gekommen, daß die ide das können sollte. auf jeden fall kann Code::Blocks sowas nicht. Code::Blocks ist eindeutig sparsam mit features (hoofentlich bleibt das auch so).

    und was heiß es, eine funktion zu extrahieren?



  • Aso, dann arbeitest du aber immer noch mit dem Iterator. Ein nettes Spielzeug ist es, aber an die Eleganz von

    List<int> foo = new List<int>();
    
    foreach( int x in foo )
        sum  +=  x;
    

    kommt es so noch nicht ran. Es müsste doch möglich sein, in dem Makro den Iterator gleich zu dereferenzieren und einer Referenz auf das aktuelle Objekt den Namen zu geben, den man als Parameter angibt, oder?



  • volkard schrieb:

    Optimizer schrieb:

    Ich möchte die Frage präzisieren. Beherrscht es einfaches Refactoring wie etwas umzubenennen oder Funktion extrahieren?

    äh. umbennenen macht man mit search&replace, oder? naja, man nennt es einfach um und fragt den compiler, wo's vorkommt, und macht die fehler alle raus. bin nir drauf gekommen, daß die ide das können sollte. auf jeden fall kann Code::Blocks sowas nicht. Code::Blocks ist eindeutig sparsam mit features (hoofentlich bleibt das auch so).

    und was heiß es, eine funktion zu extrahieren?

    Jede brauchbare Java- und C#- IDE kann das. Du machst einen Rechtsklick auf die Variable, Klasse, Funktion, Typparameter, sonstwas, sagst umbenennen und gibst nen neuen Namen an. Das ist um Welten besser als search & replace, weil dabei nichts kaputt gehen kann. Die IDE sagt dir, wenn das Umbenennen Ärger macht, weil es bereits eine andere Variable in dem Scope mit gleichen Namen gibt und sie benennt auch nichts um, was was anderes ist und nur zufällig genauso heißt.

    Funktion extrahieren ist folgendes:

    int a, b;
    ...
    foo( a >= b  ?  a : b );
    ...
    foo( a >= b  ?  a : b );
    

    Du markierst den Ausdruck "a >= b ? a : b", sagst extract method, gibst nen Namen ein und die IDE erstellt ne Methode

    int max(int a, int b)
    {
        return a >= b  ?  a : b;
    }
    

    und ersetzt jeden Code dieser Form durch den Aufruf.

    Kann auch sehr praktisch sein. Außerdem erwarte ich von einer IDE wenigstens noch, dass sie die Reihenfolge der Parameter bei einer Funktion ändern kann und alle Aufrufe anpasst. Das kannst du mit dem Compiler auch nicht immer, wenn du die Reihenfolge zweier Parameter vertauscht, die sich ineinander umwandeln lassen.



  • Kleiner Auszug aus dem, was Eclipse so kann:

    Rename
    Move (Klasse in einen anderen namespace (in java package natürlich) schieben
    Change Method signature (Reihenfolge vertauschen, Parameter entfernen)
    Convert anonymous class to nested
    Push down (Vererbungshierarchie)
    Pull up (Vererbungshierarchie)
    Extract Interface (aus Klasse)
    Generalize Type
    Use Supertype where possible
    Inline
    Extract Method
    Introduce Parameter
    Introduce Factory
    Convert local variable to field
    Encapsulate Field (getter und setter erstellen und private machen)

    das waren jetzt nicht alle, aber IMHO die interessantesten. Sowas kann es schon erheblich erleichtern, nachträglich den Code zu verbessern.



  • Optimizer schrieb:

    Aso, dann arbeitest du aber immer noch mit dem Iterator.

    ja. andere wege habe ich verworfen, weil ich nicht fordern will, daß isteratoren klein sind und schnell kopiert werden können. also meine bäume werden keine auswärtszeiger kriegen, wie die stl-baume, nur damit man einfach durchiterieren kann.

    List<int> foo = new List<int>();
    
    foreach( int x in foo )
        sum  +=  x;
    

    kommt es so noch nicht ran. Es müsste doch möglich sein, in dem Makro den Iterator gleich zu dereferenzieren und einer Referenz auf das aktuelle Objekt den Namen zu geben, den man als Parameter angibt, oder?

    dich stört nir das *i statt i?
    klar kann man das wegmachen. aber das wäre imho konzeptionell falsch und letztlich auch für den anwender unfreundlich. ich will c++ nur vereinfachen, nicht javaisieren.

    ganz in der nähe deiner absicht war ich, als ich mit sowas experimentierte:

    template<typename T>
    struct Runner{
       T begin;
       T end;
       ...
       operator DraufgezeigterTyp(T)&(){
          return *begin;
       }
       operator bool(){
          return begin!=end;
       }
       void operator++(){
          ++begin;
       }
    };
    


  • volkard schrieb:

    dich stört nir das *i statt i?

    Ja. bzw. das (*i)->foo(), wenn ich in der Collection Zeiger ablege.

    klar kann man das wegmachen. aber das wäre imho konzeptionell falsch und letztlich auch für den anwender unfreundlich. ich will c++ nur vereinfachen, nicht javaisieren.

    Wieso wäre das konzeptionell falsch? Eine foreach loop benutzt du doch, um auf allen enthaltenen Elementen zu arbeiten. Innerhalb einer foreach loop sollte man IMHO keine Änderungen am Container durchführen können. Sobald ich nen Iterator habe, kann ich das. Das finde ich konzeptionell falsch.
    Kommt es bei dir irgendwann vor, dass du in einer foreach loop etwas anderes mit dem Iterator machst, als ihn zu dereferenzieren?



  • Optimizer schrieb:

    Jede brauchbare Java- und C#- IDE kann das. Du machst einen Rechtsklick auf die Variable, Klasse, Funktion, Typparameter, sonstwas, sagst umbenennen und gibst nen neuen Namen an. Das ist um Welten besser als search & replace, weil dabei nichts kaputt gehen kann.

    ok. vortiel von java.
    in c++ kann dabei definitiv was kaputtgehen. ich denke nur mal an SFINAE, wo nichmal der compiler bemerken würde, daß was kaputt ist. an bedingte compilierung, daß ich gerade auf win arbeite und der linux-code ausbedingselt ist und dort auch nix ersetzt werden dürfe. könnte ja auch ausgedingselt sein, weil's toter code ist oder ne sicherheitskopie.

    Funktion extrahieren ist folgendes:

    int a, b;
    ...
    foo( a >= b  ?  a : b );
    ...
    foo( a >= b  ?  a : b );
    

    Du markierst den Ausdruck "a >= b ? a : b", sagst extract method, gibst nen Namen ein und die IDE erstellt ne Methode

    das brauche ich definitiv nicht. ich schreibe nie ?: und ich baue viele einzeiler. und ich schreibe vor allem nicht {int tmp=a;a=b;b=tmp;}

    Außerdem erwarte ich von einer IDE wenigstens noch, dass sie die Reihenfolge der Parameter bei einer Funktion ändern kann und alle Aufrufe anpasst. Das kannst du mit dem Compiler auch nicht immer, wenn du die Reihenfolge zweier Parameter vertauscht, die sich ineinander umwandeln lassen.

    doch, klar. das hab ich schon vor 12 jahren gemacht. man nennt die funktion zuerst um in foo (und macht alles fehlerfrei, um jeden erwischt zu haben). und dann nennt man sie zurück und vertauscht auch die parameter.

    und für eclipse ist mein rechner eh viel zu schwach. außerdem hat mich keines der features vom sockel gehauen. es kann halt keine ide geben, die allen gefällt. kann ich mit eclipse ein eigenes makefile benutzen?



  • @Optimizer
    Hast du schon mal Eric Nieblers BOOST_FOREACH benutzt? Ist imo zumindest einen Blick wert. Und die Komplexität der Implementation zeigt, dass manche Sachen doch lieber als Sprachmittel daherkommen sollten 😉



  • Optimizer schrieb:

    Kleiner Auszug aus dem, was Eclipse so kann:

    Rename
    Move (Klasse in einen anderen namespace (in java package natürlich) schieben
    Change Method signature (Reihenfolge vertauschen, Parameter entfernen)
    Convert anonymous class to nested
    Push down (Vererbungshierarchie)
    Pull up (Vererbungshierarchie)
    Extract Interface (aus Klasse)
    Generalize Type
    Use Supertype where possible
    Inline
    Extract Method
    Introduce Parameter
    Introduce Factory
    Convert local variable to field
    Encapsulate Field (getter und setter erstellen und private machen)

    das waren jetzt nicht alle, aber IMHO die interessantesten. Sowas kann es schon erheblich erleichtern, nachträglich den Code zu verbessern.

    für C++ nehm ich unter Linux SlickEdit. Der kann sowas auch.

    Sicherlich hat der andere macken, aber im großen und ganzen ist es brauchbar.
    Auf jeden fall besser als emacs und Eclipse-C++-plugin.


Anmelden zum Antworten