Question

I have the following code:

    struct Y {
        string& s1; //string s1; throws no error
        Y( string src ) : s1(src) { cout<<"s1: "<<s1<<endl; }
        void show(){ cout<<s1<<endl; }
    };

    int main()
    {
        Y y1("Krypton");
        y1.show(); //run-time error
    }

y1.show() should display "Krypton", but I get a runtime error (due to s1 being uninitialized when y1.show() is being called?).

Q1. Why would s1 be uninitialized when it has already been initialized in the constructor initialization list? Q2. Why don't I get the same error if I use string s1; instead of the reference?

Any help would be greatly appreciated.

Regards,

Jay.

Was it helpful?

Solution

You are initializing a reference from a temporary. If you want instances of struct Y to hold an actual string, rather than just a reference, you need a member variable of type string, not reference to string.

Q1. Why would s1 be uninitialized when it has already been initialized in the constructor initialization list?

It was initialized, but to be a reference to a string that no longer exists.

Q2. Why don't I get the same error if I use string s1; instead of the reference?

If the class contains a string, then it doesn't contain a reference to a string that exists.

What string do you think the reference is a reference to?

OTHER TIPS

s1 is set to reference src, which is a temporary object and is destroyed when the constructor exists.

When you make s1 a string, it is a local copy that doesn't depend on src

Because your constructor Y(string src) accepted a template value, and s1 reference to this template value, and then you call show() print the value witch is destroty after constructor.

Answer:

1.Because the value s1 referenced is destroy after constructor.

2.If you use string s1 instead of string& s1, witch assign src yo s1 when call constructor, and show() will print the member value of s1.

If you want to pring "Krypton", you can change Y( string src ) to Y( string& src )

In your case you can initialize the temporary member variable like this

struct Y 
{
    string& s1;

    Y( string& src )
        : s1(src)
    {
        cout<<"s1: "<<s1<<endl;
    }

    void show()
    {
        cout<<s1<<endl;
    }
};

int main()
{
    string s1_real = "Krypton";
    Y y1(s1_real);
    y1.show();

    return 0;
}

Note that

  1. Constructor takes a reference (string& src not string src). Because if you use "string src" it will be a temporary variable which will be destroyed as soon as the function stack unwinds and s1 ends up being a dangling reference. If you use "string& src" there is no new memory location created; src points to s1_real and therefore s1 ends up pointing to s1_real.

  2. You create a variable (s1_real) which is used to create y1. This is because you can't take a reference of a temporary variable (you can only take a const reference, in which case src and s1 too must be declared as const references)

Always note that the lifetime of y1 must be less than that of s1_real or else y1.s1 ends up being a dangling reference

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top