Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Initializing a reference member to an object created in the initialization list

Consider the following code:

class Foo {
    Foo() {}
};

class Bar {
    Foo &Foo_ref;
    Bar() : Foo_ref() {}
};

Complied as is, I get the error:

tmp.cc: In constructor Bar::Bar():
tmp.cc:7: error: value-initialization of Foo& Bar::Foo_ref, which has reference type

I've tried every variation I can think of. What am I doing wrong? How do I initialize a reference member to a new instance? I'm using a const pointer instead of a reference as a workaround for now, but I'd prefer to use a reference.

like image 230
macdjord Avatar asked Jul 05 '12 05:07

macdjord


3 Answers

A reference must always be binded to an object. You have to pass an object you want to have reference to in your constructor

Bar(Foo &foo) : Foo_ref(foo)
{
}

If you don't want (or can't) pass Foo into Bar constructor - you have to use pointer:

class Bar {
    Foo *Foo_ptr;
    Bar() : Foo_ptr(nullptr) {}
};

You can think about the reference member variable as a pointer which must be binded in initializer list

like image 178
Andrew Avatar answered Oct 03 '22 15:10

Andrew


What's wrong with

class Bar
{
    Foo myFoo;
    Bar() : myFoo() {}
};

if you want a brand-new Foo object?

like image 39
Ben Voigt Avatar answered Oct 03 '22 15:10

Ben Voigt


Your constructor has to either take a parameter, set the reference to a member that is initialized before the reference or set the reference to a global Foo object. You can't bind the reference to a temporary (which, even if the reference is const, would only live until the constructor ends.

extern Foo gFoo;

class Bar {
    Foo foo;
    Foo &Foo_ref;
    Bar() : Foo_ref(gFoo) {}
    //or
    //Bar() : Foo_ref(foo) {}
    Bar(Foo& foo) : Foo_ref(foo) {}
};
like image 38
Luchian Grigore Avatar answered Oct 03 '22 15:10

Luchian Grigore