Wieso sind Funktionen in Klassen nicht per default virtell?



  • Also wenn ich mir diesen Thread so durchlese, frage ich mich, wieviele
    von euch sogenannten C++ Programmieren jemals richtig objektorientiert
    programmiert haben 😮

    C++-ler schrieb:

    Eigentlich sind weniger virtuelle Funktionen in einem Programm vorhanden als non-virtuelle.

    Ihr schreibt anscheinend hauptsächlich reine C-Programme, vereinzelt garniert
    mit ein oder zwei abgeleiteten Klassen als Alibi.

    Und wenn ihr euch über Performance virtueller Funktionen/Methoden so
    aufregt, bleibt doch gleich bei C. Die Sprache behauptet zumindest nicht
    objektorientiert zu sein und man muß sich auch nicht verstellen

    Alan Kay schrieb:

    Ich habe den Begriff »Objektorientiert« erfunden, und ich kann Ihnen sagen, ich hatte wahrlich etwas anderes als C++ im Kopf.

    BTW: C++-ler's Ausführungen zur Bedeutung des const-Modifiers kann ich vollkommen
    zustimmen.

    Dieses const ist eines der Sprachattribute die ich in Java vermisse 😞



  • Javaner schrieb:

    Also wenn ich mir diesen Thread so durchlese, frage ich mich, wieviele
    von euch sogenannten C++ Programmieren jemals richtig objektorientiert
    programmiert haben 😮

    Nein, das kannst du so nicht sagen. Du mußt bedenken, das wir in C++ ganz andere Sprach-Features haben, die in Java nicht vorhanden sind. Ich selbst programmiere beruflich Java, weiß also sehr wohl was OOP ist und bin auch gezwungen es so zu machen. In C++ habe ich aber z.B. Templates und Mehrfachvererbung, wo ich mit diesen beiden _kombinierten_ Features die Policy-Patterns einsetzen kann (Aspektorientiertes Design), was ich in Standard-Java praktisch nicht umsetzen kann.

    Klar, jeder kann in C++ wie in Java programmieren, auch ich ertappe mich immer wieder, das ich das so mache, weil ich es vom Beruf her so gewohnt bin. Aber das ist ja das Tolle an C++: ich kann in C++ so programmieren, wie ICH es will.



  • @ Artchi

    Als Wanderer zwischen den Welten kannst du mir
    sicher mal die Hauptunterschiede zwischen C++- und
    Java-Templates aufzählen.

    Ich weiß nur, daß Java intern ohne Code-Kopieren auskommt.

    Gibt es Einschränkungen? Kann man mit C++-Templates etwas machen,
    was in Java nicht möglich ist?



  • Javaner schrieb:

    Kann man mit C++-Templates etwas machen,
    was in Java nicht möglich ist?

    Schnell ausführen. f'`8k

    Gruß, TGGC (\-/ returns)



  • Auch 'ne Antwort 😮 😃



  • Javaner schrieb:

    Als Wanderer zwischen den Welten kannst du mir
    sicher mal die Hauptunterschiede zwischen C++- und
    Java-Templates aufzählen.

    Die "Java Templates" heißen Generics und haben außer der Syntax fast nichts mit den C++ Templates gemein. Die darf man nicht 1:1 vergleichen.

    Gibt es Einschränkungen? Kann man mit C++-Templates etwas machen,
    was in Java nicht möglich ist?

    Joah, z.B. die Fakultät zur Compile-Time berechnen:

    template <u64 N>
      struct Faculty {
        enum { result = N * Faculty<N-1>::result };
      };
    
      template < >
      struct Faculty<1> {
        enum { result = 1 };
      };
    
      std::cout<<Faculty<3>::result<<std::endl;
    

    Auch cool finde ich solche Sachen, egal in welcher Sprache. Generische Programmierung rockt halt^^:

    //Filtern wir mal alle geraden zahlen raus
      template <class T1, class T2>
      struct Mod : public unary_function<T1, T2> {
        T2 operator()(const T1& x) const { return x%2==0; }
      };
    
      template < class Func, class Cont, class Iter>
      Cont filter(const Cont &c) {
        Func f;
        Cont ret;
        for (Iter it = c.begin(); it != c.end(); ++it)
          if ( f(*it) == true)
    	ret.push_back(*it);
    
        return ret;
      };
    
      std::vector<int> v;
      for (int i=0;i<50;++i)
        v.push_back(i);
      std::vector result = filter< Mod<int, bool>, std::vector<int>, std::vector<int>::iterator > (v);
    

    Oder Policy-Design. Wurde ja schon erwähnt.

    MfG

    GPC



  • NES-Spieler schrieb:

    Naja, aber man kann Vererbung ja nicht verhindern. Sollte man also seine Memberfunktionen nicht immer virtual machen, damit jemand, der davon etwas ableitet, eben nicht obiges Problem bekommt?

    Es gibt ja nicht nur public Vererbung. Und man will auch nicht immer, dass die Funktion überschrieben wird. Manchmal reicht halt auch Überdeckung einfach aus. Schau dir zB mal die STL an, wie es hier schon erwähnt wurde. Da wirst du nicht sooo viele virtuelle Funktionen finden. Auch ist Vererbung nicht immer das geeignete Mittel der Wahl. In der STL wirst du zB Container finden, die über Layering implementiert sind. Stichwort: "ist ein", "hat ein" Beziehung.

    Wieso muß man auch diesbezüglich überhaupt durchblicken? Ich meine, was interessiert es mich, ob diese oder jene Funktion intern eine Variable ändert? Das geht doch sowieso niemanden außer den Programmierer der Klasse was an. Ich meine, es gibt ja bei Funktionen auch nicht die Möglichkeit, zu gucken, ob eine übergebener Parameter verändert wird.

    Ich weiss nicht, ob du mich überhaupt verstanden hast. Dass const existiert, sollte hoffentlich klar sein. Damit du ein Objekt erzeugen kannst, welches nach der Initialisierung konstant bleibt und nicht mehr verändert werden kann (const_cast ignorieren wir einfach mal). Wenn du also so ein const Objekt hast, willst du dann erstmal deinen Code schreiben und hinterher beim Kompilieren schauen, ob die Memberfunktionsaufrufe vom Compiler akzeptiert werden? Oder wie willst du herausfinden, ob eine Memberfunktion für const Objekte zulässig ist? Immer in die Dokumentation schauen, ob da ein entsprechender Vermerk steht? Dann kannst du auch gleich const hinter die Funktion schreiben. So kann man doch kein vernünftiges Design planen. Dass das const ein weiterer Schutzmechanismus für den Entwickler ist, der ungewolltes Verändern von Membern verhindert, wurde ja auch schon erwähnt.

    Und nochmal zur Aussage:

    das const gibst du an, damit der compiler prüft, dass du auch ja nichts veränderst und nicht umgekehrt.

    Das würde ja lediglich bedeuten, daß ich mich vor mir selbst schütze.

    U.a. Ist es nicht toll, wenn dir der Compiler sagt, dass du einen Fehler gemacht hast?

    Und nach der Logik "damit prüft der Compiler, daß Du auch ja nichts änderst/falsch machst/was auch immer" sollte das auch nicht funktionieren, denn parameter ist ein fremdes Objekt und seine Variable zahl ist privat, also sollte man sie an der obigen Stelle gar nicht verändern dürfen.

    Das ist aber ein ganz anderes Gebiet. Zwar ist es ein anderes Objekt, aber nunmal dieselbe Klasse. Ob das jetzt richtig ist oder nicht, darüber kann man diskutieren. C++ erlaubt es und fertig.

    Javaner schrieb:

    Also wenn ich mir diesen Thread so durchlese, frage ich mich, wieviele
    von euch sogenannten C++ Programmieren jemals richtig objektorientiert
    programmiert haben 😮

    Tja, und wenn ich mir deinen Nick anschaue, dann vergleichst du Java mit C++. Das ist aber genauso wenig sinnvoll, wie C mit C++ zu vergleichen.
    Java _ist_ objektorientiert, C++ nicht (auch wenn BS die Sprache deswegen entwickelt hat). C++ ist eine Multiparadigmensprache, und OO lediglich ein verwendbares Konzept. Und das ist auch das Schöne an C++, es bietet weitaus mehr als nur Interfaces. Ob du das nun verstehst oder nicht. "It's not a bug, it's a feature." 😉

    Javaner schrieb:

    Ihr schreibt anscheinend hauptsächlich reine C-Programme, vereinzelt garniert
    mit ein oder zwei abgeleiteten Klassen als Alibi.

    Und du hast offensichtlich nicht viel Ahnung von C++. Sry, aber das musste jetzt sein. 🙄

    Freak_Coder schrieb:

    Und nochwas wichtiges: Da man Parameter ja aus effiziens Gründen immer als Refernzen auf const deklarieren sollte, ist es natürlich auch sinnvoll man hat Konstante Elementfunktionen, denn ansonsten könntest du mit den Übergebenen Objekten ja fast gar nicht arbeiten...

    Nope. Das eine hat mit dem anderen nichts zu tun. Die übergebenen Parameter sind vollkommen unabhängig von this.



  • Javaner schrieb:

    @ Artchi

    Als Wanderer zwischen den Welten kannst du mir
    sicher mal die Hauptunterschiede zwischen C++- und
    Java-Templates aufzählen.

    Ich weiß nur, daß Java intern ohne Code-Kopieren auskommt.

    Gibt es Einschränkungen? Kann man mit C++-Templates etwas machen,
    was in Java nicht möglich ist?

    Die Dinge sind nicht zu vergleichen. Templates sind Vorlagen, die mit verschiedenen Parametern instanziert werden können. Du kannst zum Beispiel die Typen parametrisieren, oder auch konstante Werte.

    Generics machen nur Typersetzung und sind damit in diesem Punkt weniger flexibel. In Java ist die Implementierung sogar doppelt unglücklich, da der Typ einfach durch Object ersetzt und zur Laufzeit ständig gecastet wird. Die Generics bringen aber auch eine interessante Idee mit, die auf Templates so nicht anwendbar ist: Generischer Code kann selber (ohne konkrete eingesetzte Parameter) compiliert werden und Constraints definieren.



  • groovemaster schrieb:

    Nope. Das eine hat mit dem anderen nichts zu tun. Die übergebenen Parameter sind vollkommen unabhängig von this.

    Beispiel was ich meine, vielleicht hast du mich ja falsch verstanden oder ich dich nicht 🙂

    class MyClass {
    
    	private:
    	 		int z;
    	public:
    			MyClass():z(8) {}
    
    			int funk() const { return z; }
    };
    
    int testfunk(const MyClass& cc)
    {
    	return cc.funk();
    }
    
    int main()
    {
    	MyClass a;
    
    	int t = testfunk(a);
    
    	return 0;
    }
    

    Würde man hier die Elementfunktion ja nicht als const definieren, dann könnte man ja funk() in testfunk() nicht aufrufen.
    Meinte das nur, um zu zeigen wieso const gut ist ...



  • Aso, ich dachte du sprachst von den const Memberfunktionen und dort übergebenen const Referenz Parametern. Mit dem Beispielcode macht's natürlich wieder Sinn. 😃


Anmelden zum Antworten