Nur temporäre Instanzierung erlauben



  • Xebov schrieb:

    OK das verstehe ich, aber was ist mit Referenzen, oder Zeigern?

    foo test&=foo::make( *test* );
    
    foo *test=&foo::make( *test* );
    

    Das würde ja trotzdem noch funktionieren, oder irre ich mich?

    Vor Zeigern hatte ich ehrlich gesagt keine Angst. Es ist klar, dass man keine Zeiger auf temporäre Objekte legt.

    Don06 schrieb:

    Du musst aufpassen. Die Lebenszeit eines temporären Objektes lässt sich verlängern, wenn man es an eine konstante Refernz bindet.

    {
        foo const& foo_ref = foo::make( /* ... */ );
        fooFunc(foo_ref);
    } // Hier wird das tempräre Objekt zerstört.
    

    EDIT: Die Referenz muss auf dem Stack liegen.

    Danke für den Hinweis! Dies ist aber kein Problem, da durch die künstliche Verlängerung auch die Lebensdauer der evtl. zusätzlich erzeugten temporären Objekte verlängert wird.

    {
        foo const& foo_ref = foo::make( foo2::make() );
        fooFunc(foo_ref);
    } // Hier wird der Destruktor von foo und foo2 aufgerufen.
    


  • vultur_gryphus schrieb:

    Vor Zeigern hatte ich ehrlich gesagt keine Angst. Es ist klar, dass man keine Zeiger auf temporäre Objekte legt.

    Naja es würde es aber Möglich machen die Objekte außerhalb von Funktionsaufrufen anzulegen. Man könnte so zB irekt in Main ein Objekt anlegen das solange lebt wie das Programm lebt ohne eine Funktion aufzurufen.



  • Xebov schrieb:

    Naja es würde es aber Möglich machen die Objekte außerhalb von Funktionsaufrufen anzulegen. Man könnte so zB irekt in Main ein Objekt anlegen das solange lebt wie das Programm lebt ohne eine Funktion aufzurufen.

    Kann ich noch nicht nachvollziehen. Beispiel?

    Tatsache ist, dass folgendes verboten ist:

    foo *test=&foo::make( *test* );
    

    Durch make wird ein temporäres Objekt erzeugt und direkt nach dieser Zeile existiert das Objekt nicht mehr.



  • vultur_gryphus schrieb:

    Kann ich noch nicht nachvollziehen. Beispiel?

    Tatsache ist, dass folgendes verboten ist:

    foo *test=&foo::make( *test* );
    

    Durch make wird ein temporäres Objekt erzeugt und direkt nach dieser Zeile existiert das Objekt nicht mehr.

    Stimmt, ich stehe heute echt total neben mir, hätte den Gedanken zuende denken sollen, Standart und Copykonstruktor haste ja dicht gemacht damit käme man ja wirklich mit nichts mehr an die Klasse ran. Das ist wirklich nicht schlecht. Aber erzähl mal für was du soetwas brauchst?



  • Ich benutze solche Foo-(Temporär)-Objekte, um Funktionsaufrufe sehr flexibel parametrisieren zu können.

    Anstatt x verschiedene Funktionen namens y zu haben (x*y verschiedene Funktionen), wird einfach mittels dem temporären foo-Objekt parametrisiert. foo wird schlicht unterschiedlich konstruiert (verschiedene "makes" - named constructor idiom) und danach an eine eindeutige Funktion übergeben.



  • Interessant das kannte ich noch nicht, wobei mir bis eben auch nicht klar war das man ne Klasse ohne weiteres soweit abschließen kann das man echt fast nichtmehr ran kommt. Wieder was gelernt 🙂



  • Gern geschehen 😉

    Was mich aber zur eigentlichen Frage zurück bringt... Gibt es einen Workaround bzw. eine andere Art wie man sowas machen kann, damit es unter GNU C 4.1 läuft?



  • vultur_gryphus schrieb:

    Gern geschehen 😉

    Was mich aber zur eigentlichen Frage zurück bringt... Gibt es einen Workaround bzw. eine andere Art wie man sowas machen kann, damit es unter GNU C 4.1 läuft?

    Nein, das kann es auch nicht, da du voraussetzt, dass ein Compiler eine optionale Optimierung durchführt und die Syntax nicht vor Anwendung der Optimierung auf Gültigkeit prüft.

    Wenn du einmal auf www.comeaucomputing.com gehst und dort den Online-Compiler mit deinem Programm fütterst erhälst du ungefähr folgende Ausgabe:

    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout ! 
    
    Your Comeau C/C++ test results are as follows: 
    
    Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2007 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ noC++0x_extensions
    
    "ComeauTest.c", line 16: error: "foo::foo(const foo &)" (declared at line 5),
              required for copy that was eliminated, is inaccessible
      fooFunc(foo::make()); 
              ^
    
    1 error detected in the compilation of "ComeauTest.c".
    In strict mode, with -tused, Compile failed
    Hit the Back Button to review your code and compile options. 
    Compiled with C++0x extensions DISabled. 
    
    Don't you find "tryitout" useful? Maintaining "tryitout", keeping it up and running 24/7, etc.
    doesn't come free. It's fast and easy to send us a donation.
    
    Even better! Buy Comeau C/C++ Today ... Anything Less Is A- 
    
    Comeau C/C++ 4.3.10.1 Beta2 is now available for LINUX/Intel, Mac PowerPC, Mac Intel, 
    and Windows (including backend support of VC++ 8.0, 9.0, and now MinGW gcc 3.4.5). 
    
    Did You Know? Comeau provides C and C++ training.
    We love beginners. You'll love our insights.
    Contact us for details.
    

    Beachte auch, dass der Compiler sogar sagt, dass er die Kopie wegoptimieren wird.



  • vultur_gryphus schrieb:

    Was mich aber zur eigentlichen Frage zurück bringt... Gibt es einen Workaround bzw. eine andere Art wie man sowas machen kann, damit es unter GNU C 4.1 läuft?

    Naja was mir da nur als Idee einfällt wäre eine echte Singleton draus zu machen. Also eine einzige statische Instanz die einfach immer von deiner Funktion mit neuen Daten gefüttert und "Umgebaut" wird, wenn du da über friends arbeitest und die wichtigen Sachen versteckst wäre es für das Programm egal ob es Kopien davon gibt die durchs Programm geistern. Das ginge natürlich nur wenn du nur eine Kopie zur selben Zeit brauchst.

    Das könnte dann so aussehen:

    class foo
    {
    protected:
        foo() {}
        foo(const foo&) {}
        foo& operator=(const foo&){}
    public:
        static foo& Instance()
        {
            static foo thefoo;
            return thefoo;
        }
        static foo& make()
        {
            foo fooone&=Instance();
            modify fooone;
            return fooone; 
        }
    };
    
    void fooFunc(const foo &)
    {
    }
    
    int main()
    {
        fooFunc(foo::make());
        return 0;
    }
    

    Damit würde das ganze Funktionieren. Die frage ist halt wieweit das für dich in Frage käme.



  • Xebov schrieb:

    Naja was mir da nur als Idee einfällt wäre eine echte Singleton draus zu machen. Also eine einzige statische Instanz die einfach immer von deiner Funktion mit neuen Daten gefüttert und "Umgebaut" wird, wenn du da über friends arbeitest und die wichtigen Sachen versteckst wäre es für das Programm egal ob es Kopien davon gibt die durchs Programm geistern. Das ginge natürlich nur wenn du nur eine Kopie zur selben Zeit brauchst.

    Ja, genau daran würde es leider scheitern

    Tippgeber schrieb:

    Nein, das kann es auch nicht, da du voraussetzt, dass ein Compiler eine optionale Optimierung durchführt und die Syntax nicht vor Anwendung der Optimierung auf Gültigkeit prüft.

    Nein, das setze ich nicht voraus. Selbst wenn er nicht optimiert und den CC braucht, er darf doch? Innerhalb von "make" ist der CC ja verfügbar. Außerhalb von "make" hat der Compiler doch nur die temporäre per const ref zu übergeben.

    Ich verstehe also nicht, warum er hier meckert. Wie gesagt, die neueren GCC schlucken es ja auch!

    Tippgeber schrieb:

    "ComeauTest.c", line 16: error: "foo::foo(const foo &)" (declared at line 5),
    required for copy that was eliminated, is inaccessible
    fooFunc(foo::make());
    ^


Anmelden zum Antworten