Zugriffsverweigerung bei Destruktor


  • Mod

    Shade Of Mine schrieb:

    camper schrieb:

    Bleibt noch anzumerken, dass es - meiner Meinung nach - fast nie sinnvoll ist, den Rückgabetyp konstant zu machen (wie oben geklärt, spielt es sowieso nur bei Klassen eine Rolle). Die Gründe dafür sind nicht sonderlich kompliziert. Hauptsächlich geht es um Kapselung - eine Funktion sollte so wenig wie möglich vom Aufrufer verlangen (=möglichst allgemeiner Parameter) und möglichst viel versprechen (=Garantien über die Rückgabe liefern, mit einem veränderbaren Objekt kann man mehr machen, als mit einem konstanten), aber das sprengt ein bisschen den Rahmen dieser Diskussion.

    Und deshalb ist es gut
    (a+b)=c;
    zu erlauben?

    Ich sehe daran nicht so viel Schlimmes. Die geerbte C-Syntax erlaubt ohnehin eine Menge Mist. Schreibt man das mit Klammern, ist sowieso Machiavelli am Werk - oder jemand mit einem Klammerfetisch (etwas, das ich nicht besonders mag, es kann helfen Präzedenz zu klären, aber häufig wird ein Ausdruck auch unverständlicher, wenn man nur nach am Klammerabzählen ist). Gefährlich könnte es werden, wenn wir eigentlich einen Vergleich schreiben wollten. Das passiert für gewöhnlich in if,while-statements; und hier sind moderne Compiler in der Regel sehr mitteilungsfreudig - es ist also imo kein praktisches Problem, wenn man die Warnungen des Compilers gelegentlich liest. Es bliebe der Fall, wenn der eigentlich gewollte Vergleich nur ein Subausdruck ist. Solche Fälle sind eher selten und per se schwerer zu verstehen, hier ist in jedem Falle erhöhte Aufmerksamkeit gefordert, oder man verzichtet darauf - auch ein C-Erbe i.w.S.

    Wäre es gut, es nicht zu erlauben? Sicherlich, aber das Mittel ist ungeeignet. Der Defekt, wenn man das so bezeichnen will, liegt ja beim Zuweisungsoperator, nicht bei der Addition.
    Und dann wäre da noch
    c=a+b
    Ist obiges Problem wirklich so gravierend, dass wir mit Freude auf Move-Kopiererei verzichten würden? Da habe ich große Zweifel.
    Persönlich finde ich, dass das a+b=c Problem unnötig aufgebauscht wurde. Hier wird eine relativ isolierte Problematik zum Anlass genommen, potentiell das Design nahezu jeder Funktion zu beeinflussen.



  • camper schrieb:

    Ist obiges Problem wirklich so gravierend, dass wir mit Freude auf Move-Kopiererei verzichten würden?

    Warum sollte ein move nicht funktionieren? Wenn ich mir zB Mojo ansehe - dann wuerde (a+b)=c wohl sowieso nicht klappen.

    oder uebersehe ich etwas? welchen nachteil hat es, ein (a+b)=c zu verbieten und sich so an die builtin semantic zu halten. denn zuweisung an temopraere objekte ist immer boese. es sei denn jemand hat eine situation wo das sinn machen kann...


  • Mod

    Shade Of Mine schrieb:

    camper schrieb:

    Ist obiges Problem wirklich so gravierend, dass wir mit Freude auf Move-Kopiererei verzichten würden?

    Warum sollte ein move nicht funktionieren? Wenn ich mir zB Mojo ansehe - dann wuerde (a+b)=c wohl sowieso nicht klappen.

    oder uebersehe ich etwas? welchen nachteil hat es, ein (a+b)=c zu verbieten und sich so an die builtin semantic zu halten. denn zuweisung an temopraere objekte ist immer boese. es sei denn jemand hat eine situation wo das sinn machen kann...

    Ich glaube wir reden aneinander vorbei. Ich habe nichts dagegen a+b=c zu verbieten, sofern die Methode nicht darin besteht, Funktionsergebnisse konstant zu machen. Die Frage ist doch gar nicht, ob es gut oder schlecht ist so etwas zu verbieten, sondern ob es den Preis wert ist, indem automatisch andere sinnvolle Konstrukte gleichzeitig unmöglich werden.
    Ob Zuweisung an temporäre Objekte wirklich so furchtbar böse ist, kann auch bezweifelt werden oder ist eine Frage, wie das zu verstehen sein soll: im Allgemeinen ist es nur sinnlos, als böse würde ich etwas erst bezeichnen, wenn es versehentlich etwas anderes als das Offensichtliche tut oder leicht unbemerkt als versehentlicher Schreibfehler entsteht. Zu Ersteres fällt mir nichts ein, für Letzteres gibt es meiner Erfahrung nach adäquate Compilerunterstützung.

    Wenn a+b konstant ist (und nur darum geht es), kann c=a+b keine move-Unterstützung anbieten (unabhängig vom System, ob nun mit Mojo, Abrahams' Methode oder rvalue-Referenzen) ohne undefiniertes Verhalten zu provozieren. Move-Unterstützung ist nur ein Fall, es gibt viele Fälle in denen wir ein temporäres Objekt zwar nicht zuweisen aber doch verändern wollen. In Abwesenheit von Move-Semantik (und Expression Templates etc), könnte zum Beispiel so etwas sinnvoll sein:
    a=((a*b)+=c);
    oder
    foo((a+b).trim()) (a,b: irgenwelche strings)
    keines dieser Beispiele ist für sich genommen besonders wichtig und man könnte ohne Weiteres darauf verzichten (in der Regel machbar, wenn wir eine zusätzliche Variable an Stelle des temporären Objektes einführen und auf Copy-Elision vertrauen), in ihrer Gesamtheit erscheint mir das Verbot dieser ganzen Klasse von Konstrukten übertrieben nur um ein relativ obskures Problem mit der Zuweisung zu lösen, mit dem ich noch nie zu tun hatte. Abgesehen von diesen Beispielen gefällt es mir schon systematisch nicht, weil an der falschen Stelle angesetzt wird und auch nicht aus sich selbst heraus begründet werden kann, mit der Aufgabe der Funktion, die betroffen ist, hat das Ganze schließlich nichts zu tun. Die Argumentation mit der "built-in-Semantic" ist da ein bisschen fragwürdig. Wenn wir dahin wollen, müssen wir dem Ergebnis solcher Operatoren den Objektcharakter wegnehmen (offensichtlich unmöglich), mit const kommen wir nicht dahin.

    Ich halte es nicht für richtig, dem Nutzer Konstrukte, die wir ggf. mißbilligen, zu verbieten, wenn eine Empfehlung in dieser Hinsicht genügen müsste. Zumindest erscheint mir das Problem einfach nicht schwerwiegend genug um einen dermaßen massiven Eingriff in die Deklaration jeder einzelnen Funktion, die Klassenobjekte zurückgibt, zu rechtfertigen.


Anmelden zum Antworten