Warum kann ich diese Referenz so nicht initilalisieren?



  • Hallo Forum,

    ich möchte gerne eine Referenz initilalisieren. Warum geht das so nicht?

    #include <string>
    #include <iostream>
    
    class Abc{
    public:
    	const std::string &sName;
    	Abc(const char * cName) : sName(cName) {
    	}
    };
    
    int main(){
    	Abc test("abc123");
    	std::cout << "---" << test.sName << "--" << std::endl; // abc123 wird nicht ausgegeben.
    }
    

    Der Kompiler meint schon beim Kompilieren:

    Der Verweismember wird mit einem temporären Wert initialisiert, der nach dem Beenden des Konstruktors nicht beibehalten wird.

    Im Konstruktor wird doch der char* in ein std::string umgewandelt. Warum wird dieser dann nicht sName zugewiesen? Mir geht es mehr ums Verstehen als darum den Code zum Laufen zu bekommen.

    Vielen Dank

    Barney



  • Barneygrps schrieb:

    Der Kompiler meint schon beim Kompilieren:

    Der Verweismember wird mit einem temporären Wert initialisiert, der nach dem Beenden des Konstruktors nicht beibehalten wird.

    Im Konstruktor wird doch der char* in ein std::string umgewandelt.

    Richtig. In ein temporäres Objekt vom typ std::string.

    Warum wird dieser dann nicht sName zugewiesen?

    Wird er doch. Die Referenz wird an das temporäre Objekt gebunden. Genau das bemängelt der Compiler ja auch. Das temporäre Objekt ist sofort nach dem Ctor-Aufruf zerstört und der Zugriff auf die Referenz undefiniertes Verhalten.



  • Der Char-Pointer wird in ein String umgewandelt, richtig. Und eine Referenz auf dieses temporäre Objekt speicherst du.



  • Ach so, die Referenz ist sowas wie ein Pointer. Da das String Objekt jedoch nur während des Ctor Aufruf exisitiert ist es danach wieder ungültig.

    Ich habe den CTor Aufruf erstmal so geändert:
    Abc(const char * cName) : sName(*(new std::string(cName))) {}
    So häßlich wie das aussieht werd' ich da nochmal umdesignen...

    Vielen Dank Pumuckl und Fellhuhn 🙂



  • Mach es einfach so:

    #include <string>
    #include <iostream>
    
    struct Abc
    {
        std::string const sName;
    
        Abc(const char * cName)
        : sName(cName)
        {}
    };
    
    int main(){
        Abc test("abc123");
        std::cout << "---" << test.sName << "--" << std::endl;.
    }
    


  • Die Frage ist trotzdem interessant. Laut Standard sind const references auf temporaries erlaubt, warum beschwert sich der Compiler hier?


  • Administrator

    DocShoe schrieb:

    Die Frage ist trotzdem interessant. Laut Standard sind const references auf temporaries erlaubt, warum beschwert sich der Compiler hier?

    1. Ich denke, dass mit beschweren hier eine Warnung gemeint ist.
    2. Wieso diese Warnung kommt, wurde von pumuckl und Fellhuhn erklärt.

    Grüssli



  • DocShoe schrieb:

    Die Frage ist trotzdem interessant. Laut Standard sind const references auf temporaries erlaubt, warum beschwert sich der Compiler hier?

    http://herbsutter.wordpress.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

    sagt da was, man achte auf die Details:

    However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself

    Da Objekte mal auf dem Stack und mal auf dem heap liegen können heißt das wohl im Ganzen, dass sich das nur auf ref-to-const in Funktionsblöcken bezieht sowie auf globale.


Log in to reply