Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The constness of a variable and its lifetime

Tags:

c++

So from a question asked in another thread, I have thought of a new question and the answer is not obvious to me.

So it appears there is a c++ rule that says if you have a const reference to a temporary, then the lifetime of the temporary is at least as long as the const reference. But what if you have a local const reference to another object's member variable and then when you leave scope - Does it call the destructor of that variable?

So here is modified program from the original question:

#include <iostream>
#include <string>
using namespace std;

class A {
public:
   A(std::string l) { k = l; };
   std::string get() const { return k; };
   std::string k;
};

class B {
public:
   B(A a) : a(a) {}
   void b() { cout << a.get(); }  //Has a member function
   A a;
};

void f(const A& a)
{  //Gets a reference to the member function creates  a const reference
     stores it and goes out of scope
 const A& temp = a;
 cout << "Within f(): " << temp.k << "\n";
}

int main() {
   B b(A("hey"));

   cout << "Before f(): " << b.a<< "\n";

   f(b.a);

   cout << "After f(): " << b.a.k << "\n";

   return 0;
}

So when I run this code, I get "hey" as the value everytime. Which seems to imply that a local const reference does not bind itself through life with a passed in member object. Why doesn't it?

like image 760
nndhawan Avatar asked Dec 17 '22 01:12

nndhawan


2 Answers

b.a is not a temporary so its lifetime is not affected by any references that are subsequently bound to it.

like image 80
CB Bailey Avatar answered Jan 05 '23 02:01

CB Bailey


I'm not sure I understand what you're asking. In your code, the only temporary I see is the A("hey") in the expression that initializes b in main. And that is copied (using the copy constructor) into b.a in B::B. After that, there are no more temporaries, anywhere.

More generally, the fact that a temporary is bound to a reference doesn't necessarily change its lifetime. What extends the lifetime is the fact that the temporary is used to initialize the reference: in your case, for example, temp in f will never have an effect on the lifetime of a temporary, because it is not initialized with a temporary, but with another reference. And there are exceptions to this rule: if you use a temporary to initialize a member reference in the initializers of a class, it's lifetime will still not extend beyond the end of the constructor, so:

class A
{
    std::string const& rString;
public:
    A() : rString( std::string( "hey" ) ) {}
    std::string get() const { retur rString; }
};

will not work.

like image 28
James Kanze Avatar answered Jan 05 '23 00:01

James Kanze