I have this code:
#include <iostream>
using namespace std;
struct X {
int a = 1;
};
struct Y {
X &_x;
Y(X &x) : _x(x) {}
};
// intentionally typoed version of Y, without the reference in the constructor
struct Z {
X &_x;
Z(X x) : _x(x) {}
};
int main() {
X x;
Y y(x);
Z z(x);
cout << "x: " << &x << endl;
cout << "y.x: " << &y._x << endl;
cout << "z.x: " << &z._x << endl;
}
I keep finding myself forgetting the & in the constructor of my classes of this format.
This outputs the following:
x: 0xbfa195f8
y.x: 0xbfa195f8
z.x: 0xbfa195fc
Why is the behaviour different in the case of y and z?
And why is it not an error to initialize the X &_x member with an instance of type X in the constructor of Y?
A copy of the object is created when the constructor is called, hence the different output for z.x. The lifespan of that object is very limited – it exists only in the constructor. This is undefined behavior and the reference will be come invalid.
To prevent such behavior in your applications it is a good practice to mark the copy constructor and assignment operator private.