Initialising Reference in Constructor C++

Initialising reference in constructor C++

There is no such thing as an "empty reference". You have to provide a reference at object initialization. Put it in the constructor's base initializer list:

class c
{
public:
c(int & a) : i(a) { }
int & i;
};

An alternative would be i(*new int), but that'd be terrible.

Edit: To maybe answer your question, you probably just want i to be a member object, not a reference, so just say int i;, and write the constructor either as c() : i(0) {} or as c(int a = 0) : i(a) { }.

Initializing a reference variable in a class constructor

Since data is a reference, you must initialize it at constructor initializer:

AVLNode(T & newData): data(newData) {

}

You may find this post useful: reference member variable must be initialized at constructor initialization list. You may also need to understand the difference between initialization and assignment when you write a class's constructor.

Quoting from C++ Primer pp455:

Some members must be initialized in the constructor initializer. For such members, assigning to them in the constructor body doesn't work. Members of a class type that do not have default constructor and members that are const or reference types must be initialized in the constructor initializer regardless of type.

How can I initialise a reference member in the default constructor?

You need to use the member initialization list:

struct foo
{
const int& ref;
foo() : ref(some_value()) { }
}

Make sure some_value() doesn't give you a temporary. It will only have its life extended until the end of the constructor:

A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.

Default constructor for a class with a reference data member?

A class with a reference member needs to set the reference in its constructors. In most cases this means, that the class cannot have a default constructor. The best way to solve the problem is use a pointer instead of a reference:

class MyClass{
public:
MyClass() : s_(0) {}
MyClass(Something* s) : s_(s) {}
Something* s_;
}

C++ initialize reference with expression at constructor

If the size of Pie object is not critical, one possible solution is to let Pie manage optional Lemon:

class Pie
{
std::optional<Lemon> lemon_;
AbstractFruit& fruit_;

public:
Pie(AbstractFruit& fruit) : fruit_(fruit) {}
Pie(int size) : lemon_(size), fruit_(*lemon_) {}
};

std::optional is optional, std::unique_ptr can be used instead:

class Pie
{
std::unique_ptr<Lemon> lemon_;
AbstractFruit& fruit_;

public:
Pie(AbstractFruit& fruit) : fruit_(fruit) {}
Pie(int size) : lemon_(std::make_unique<Lemon>(size)), fruit_(*lemon_) {}
};

In the first case, Lemon will be stored inside Pie itself, in the second case, Lemon will be allocated on heap, and Pie will store only a pointer to it. If Lemon size is small (<= sizeof(void*)), std::optional is a better option.

Note that the members are initialized in order of declaration in the class, that's why lemon_ declaration should come before fruit_ one.

Must a reference type be initialized in constructor initialization list?

Does any class-member reference type must be initialized in the constructor initialization list?

Yes.

If so, why? Is that related somehow to the fact the a reference type can never be reassigned?

That's part of the reason. The other part is because a reference must be initialized, and it has no default constructor.

Are there more types that must be initialized in constructor initialization list?

Any type that doesn't have an assignment operator (be it copy or move) or default constructor. This obviously includes (but is not limited to) const members as they can't be modified once they've been constructed.


As a rule of thumb, you should (almost) always prefer to initialize your members in the constructor's initialization list: why waste cycles first default-constructing an object and then only assigning to it (if this is even possible), when you could construct it correctly in the first place?

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

What's wrong with

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

if you want a brand-new Foo object?

Initialize reference member in class C++

References are basically like pointers, but with two very important difference: a) they must be initialized when created (in order to minimize the possibility of having a dangling references in contrast to a dangling pointer), and b) cannot change the object they point to.

In your code, you have the needs that maybe can be covered by b), but not for a)(you say you'll get the value for _userBody "later", not in the time of building the object), so the you've only two possibilities left: use a simple object (which you can initialize by copying the new value) [not very good], or just use a pointer instead of a reference.

class SampleClass {
public:
SampleClass(bool mirror=false);
void updateFunction();
private:
BodyTrackeDevice _device;
BodyBlob * _userBody;
BodyMuscle _muscle;
bool _mirror;
};

SampleClass::SampleClass(bool mirror)
{
this->_mirror = mirror;
}

void SampleClass::updateFunction()
{
_userBody = &( device.getTrackedBody[ 0 ] );
}

Hope this helps.

Reference member variable initialization error with default constructor

why defining a default constructor throws compilation error?

It's not that you define a default constructor, it's that the default constructor's definition doesn't initialize i. You are required to initialize all member variables that are references, and your empty definition does not do that.

This is for the same reason that you are required to initialize reference variables:

void foo() {
int &i; // error: declaration of reference variable 'i' requires an initializer
}

why would the compiler allow declaration of default constructor(without definition)

Because the definition is the problem, not the declaration. For example, moving the ill-formed constructor definition outside of the class definition will yield the same error:

class SomeClass
{
public:
SomeClass();
int &i;
};

SomeClass::SomeClass() {} // error: constructor for 'SomeClass' must explicitly initialize the reference member 'i'

The only problem with both examples is that you're not initializing i.

Take note of the following examples, which will compile. Note that the constructor's declaration does not change, but the definition does initialize i.

int someGlobalInt;

class SomeClass
{
public:
SomeClass() : i(someGlobalInt) {}
int &i;
};

int someGlobalInt;

class SomeClass
{
public:
SomeClass();
int &i;
};

SomeClass::SomeClass() : i(someGlobalInt) {}


Related Topics



Leave a reply



Submit