Reputation: 280
class Temp {
public :
Temp(X& x): x_(x) {}
Temp(X& x, Y& y) : x_(x), y_(y) {}
...
private:
X& x_;
Y& y_;
}
I got the error because in case of Temp(X& x): x_(x)
the reference y_
is not initialized. What is the common practice to write such a class correctly ?
Upvotes: 11
Views: 10067
Reputation: 61643
The common practice, in all honesty, is to not use references as data members of a struct or class.
Why do you think you want to do this? A reference is, conceptually, another name for an already existing thing. Objects are, well, objects. You ought to be able to create them out of whole cloth. Sometimes they'll have pointers (or instances of some smart pointer class) to other stuff that already exists, but at least the pointer itself is real data.
Upvotes: 2
Reputation: 39926
Having a data member that is a reference is a STRONG contract: It means you CANNOT have a nullptr or undefined object, your class Needs this object, the object needs to exist.
As a consequence your first constructor violates this strong contract, and accordingly cannot compile.
As karlphillip suggests: you should use pointers since you do not want to respect such a contract that assures that _y is always defined.
It is valid having references as member, if your class doesnt have sense without the pre-existence of the referenced objects.
Upvotes: 7
Reputation: 93468
I will suggest another approach, even though that may be not what you are looking for.
It doesn't use reference variables (memory pointers instead), it also doesn't use boost, but it will allow you to keep both constructors without spending any more memory resources.
#include <iostream>
class Temp
{
public :
Temp(int& x): x_(&x), y_(NULL) {}
Temp(int& x, int& y) : x_(&x), y_(&y) {}
void print() { std::cout << "*x_: " << *x_ << std::endl; }
private:
int* x_;
int* y_;
};
int main()
{
int x = 5;
Temp tmp(x);
tmp.print();
return 0;
}
Upvotes: 11
Reputation: 58715
Eliminate the first constructor or eliminate the second reference. If you have a reference then you must initialize it right away. If you must provide a constructor that default-initializes the Y
member then make the Y
member a pointer or an automatic variable.
Upvotes: 0
Reputation: 53516
You have a reference to y_! References must be initialed and your first constructor does not. If you can't bind to y when the class is created you should probably use a pointer.
Upvotes: 1
Reputation: 33655
You cannot have reference members that aren't initialized! If this is the case, consider wrapping the reference in a boost::optional
, then you can optionally construct the reference.
EDIT: here is the boost::optional
approach...
class Temp {
public :
Temp(X& x): x_(x) {}
Temp(X& x, Y& y) : x_(x), y_(y) {}
...
private:
X& x_;
boost::optional<Y&> y_; // by default this is constructed with none_t
}
Upvotes: 10