5
class ClassB {
    int m_b;
public:
    ClassB(int b) : m_b(b) {}
    void PrintClassB() const {
        cout << "m_b: " << m_b << endl;
    }
};


int main(int argc, char* argv[])
{
    const ClassB &af = ClassB(1);
    af.PrintClassB(); // print m_b: 1 with vs2008 & gcc 4.4.3
}

Given the above code, I have difficulties to understand this snippet:

Q1> What does this line mean?

const ClassB &af = ClassB(1);

Here is my understanding:

af refers to a temporary variable ClassB(1) and after the

execution of this line, the temporary variable is destroyed and af refers to an undefined variable. During this procedure, no copy-constructor is called.

Then why we can still issue the following statement and obtain the results?

af.PrintClassB(); // print m_b: 1 with vs2008 & gcc 4.4.3
q0987
  • 34,938
  • 69
  • 242
  • 387
  • Obligatory: [GotW #88: A Candidate For the “Most Important const”](http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/). – GManNickG Aug 12 '11 at 05:12
  • 1
    The flurry of answers below correctly tell you why it works. But there are many programs which result in [undefined behavior](http://stackoverflow.com/questions/367633/what-are-all-the-common-undefined-behaviour-that-a-c-programmer-should-know-abo), where the program may work the way you expect 99.999% of the time; but just by coincidence. Replace your temp object with an explicit new and delete, and I bet you'll still obtain results. Usually :-) – leedm777 Aug 12 '11 at 05:25
  • @dave: I don't follow your deduction, sorry. This program works 100% of the time on conforming compilers, nor do I see anything in this program that ought to be replaced by new/delete. – GManNickG Aug 12 '11 at 05:28
  • @GMan: I was responding to "why we can still issue the following statement and obtain the results?". Even though the program stated is valid, you may obtain results from an invalid program (meaning one that has undefined behavior). `ClassB *af = new ClassB(1); delete af; af->PrintClassB()` would be an invalid program, yet (usually) yield the same result. – leedm777 Aug 12 '11 at 05:42
  • 1
    Is there a good reason why writing `const ClassB &af = ClassB(1);` would be better than just `const ClassB af(1);`? – DanS Aug 12 '11 at 08:16

4 Answers4

6
const ClassB &af = ClassB(1);

const here extend the life time of the temporary object (i.e., ClassB(1)) being created. It's scope lasts until af falls out of scope;

af.PrintClassB(); // print m_b: 1 with vs2008 & gcc 4.4.3

This is because, af is nothing but the temporary object's reference which was constructed passing 1 to it's constructor.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • 2
    `const` doesn't do anything, per se, but it's binding to a reference is what extends the lifetime. It just so happens that it needs to be const to be bound. (But consider in C++0x you could also do `ClassB&& af = `.) – GManNickG Aug 12 '11 at 05:10
  • 2
    @GMan: Exactly, to be clearer: **A temporary cannot be bound to a non-const reference, but it can be bound to const reference.** – Alok Save Aug 12 '11 at 05:17
5

What you see is guaranteed by the Standard.

C++03 12.2 Temporary objects:

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below...

[Example:

class C {
    // ...
public:
    C();
    C(int);
    friend C operator+(const C&, const C&);
    ˜C();
};
C obj1;
const C& cr = C(16)+C(23);
C obj2;

..a third temporary T3 to hold the result of the addition of these two expressions. 
The temporary T3 is then bound to the reference cr..The temporary T3 bound to the
reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the
program. 

—end example]

Eric Z
  • 14,327
  • 7
  • 45
  • 69
3

I think you could rely on this exemple from Herb Sutter's blog to help you with your understanding of references, const references and their lifetime.(http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/)

From his blog :

Normally, a temporary object lasts only until the end of the full expression in which it appears. 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, and thus avoids what would otherwise be a common dangling-reference error

Drahakar
  • 5,986
  • 6
  • 43
  • 58
1

No, You misunderstand the behavior, It is a well defined Behavior.

The lifetime of the temporary bound to a const reference extends till the lifetime of const.

Thus the lifetime of temporary returned from ClassB(1) is thus extended till life time of af which is closing brace of main.

Alok Save
  • 202,538
  • 53
  • 430
  • 533