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
Why Doesn't the Program Crash When I Call a Member Function Through a Null Pointer in C++
C++ Destruction of Temporary Object in an Expression
Std::Bind VS Lambda Performance
Qt Undefined Reference to Vtable
What Is the Rule That Allows 'This->' to Access Members of Dependent Base Classes
Can Virtual Functions Be Constexpr
Why "Long Int" Has Same Size as "Int"? Does This Modifier Works at All
C Static Array Initialization - How Verbose Do I Need to Be
How to Stop Windows from Blocking the Program During a Window Drag or Menu Button Being Held Down
How to Assign Two Dimensional Array to **Pointer
How to Invoke Pointer to Member Function When It's a Class Data Member
Cancel Async_Read Due to Timeout
Send Binary File Over Tcp/Ip Connection