Initialization of Object Reference Members

Started by
5 comments, last by phresnel 15 years, 3 months ago
Hello Consider the following code: class B { public: B(int bb):b(bb){} int b; }; class A { public: A(int aa):a(aa),b((B(10))){} int a; const B& b; }; It gives me the compiler error : "'A::b' : initialization of reference member requires a temporary variable" So assume that the member reference B can not be initialized because it is bounded to temporary object, as soon as the constructor finish the object with which it is initialized will be deleted. But why the following works : class B { public: B(int bb):b(bb){} int b; }; class A { public: A(int aa):a(aa),b(&(B(10))){} int a; const B* b; }; int main() { A a(6); cout<<a.b->b<<endl; //here it prints 10, I expect to break cout<<a.a<<endl; } I was excepting the program to break cause it is dereferencing temporary object that is deleted, but no, it prints the value corretly which is 10. The example is the same as above , here I just made the object member to be pointer. Any thoughts
Advertisement
I'm not entirely shure, but I thought the memory of a POD variable is not reset to a value if it's removed from memory (either by delete or by 'out-of-scope' <-- how is that called :)? ).

Mabye it will be overwritte, if you push some more objects onto the stack (this is a guess again) the value your pointer points to should change as well. You could try some int b[100] between A a(6) and the cout, paired with a zeromemory to clear all of the array to a certain value.

*edit*
On a second thought, I can't believe that VS keeps track of every byte of allocated memory, just to break if you've done something wrong (though it would have cut down my bug-searching to some minutes). That's what this cxcxcx (or whatever value is used in debug mode) is used for unitialized memory.
Tnank u for the reply
Well I try it and it still prints the value.
this is so weird, but I think this is definetely wrong.
Also if I replace my B* member to be string* the program crashes.
can someone explain this behavior?
Quote:Original post by elih1
It gives me the compiler error :
"'A::b' : initialization of reference member requires a temporary variable"


That is correct, you're storing reference to temporary object, which will no longer exist once that part of code is done.

Quote:But why the following works :

It doesn't.

Quote:I was excepting the program to break cause it is dereferencing
temporary object that is deleted, but no, it prints the value corretly which is 10. The example is the same as above , here I just made the object member to be pointer.


Since you're dereferencing an invalid pointer, the results are undefined. C++ cannot "break". Invalid reference may result in expected result, unexpected result, system fault of sorts, or something else. Hence - undefined.

Pointers are unchecked, and may contain anything.

When using references, compiler warns you. If you change to pointer, the problem is still there, compiler just doesn't warn anymore, since that is valid code, even if results are potentially undefined.

For example, storing that pointer is perfectly fine - as long as you don't dereference it.
To initialise references, the referencee's lifetime must be longer than the reference's lifetime.

class Foo {}class Bar {        Foo &foo;        Bar (); // forbid this constructor explicitly by making it private    public:        Bar (Foo &foo) : foo (foo) {}};int main () {    Foo myFoo;    Bar myBar (myFoo);}



There's a trick anyways:

class Foo {}class Bar {        static Foo foooo;        Foo &foo;    public:        Bar (Foo &foo) : foo (foo) {}        Bar () : foo (foooo) {}};Foo Bar::foooo;int main () {    Foo myFoo;    Bar myBar;}


[Edited by - phresnel on January 7, 2009 1:10:46 PM]
Thank you
Quote:Original post by elih1
Thank you


Not too fast [smile]

I forgot the usage examples (in main()).

Btw, no problem!

This topic is closed to new replies.

Advertisement