> but i cant' figure out why this couldn't work:
It will work if your class constructor assigns to rInputMap on the derivation list.
References combine three elements of code that are sometimes hard to distinguish; Initialization versus assignment, copy-initialization versus direct-initialization and declaration versus definition.
Let's start, shall we?
For now keep this in mind; You can't do this:
Code:
int val;
int& value;
value = val;
you have to do this:
Code:
int val;
int& value = val;
The thing with references is that they have to be initialized at the point of definition.
Now... forget that for a moment and let's go back. There's two types of initializations; copy-initialization and direct-initialization. You can express them with objects of built-in type as such:
Code:
int val = 13; // copy initialization
int val(13); // direct initialization
Both define an object of type int, named val, and assign 13 to it. But they do it in different ways. The first creates a temporary object with the value 13 and then copies this object to val. The temporary is then discarded. The second directly initalizes val with 13.
And this is where we go back to the references above. Your class constructor can have an initialization list. The real effect of this initialization list is to direct-initialize your data members. Everything else that happens inside the constructor will be copy-initialized.
Code:
class myClass {
public:
myClass(int x): val1_(x), val2_(13) { val3_ = 14; }
private:
int val1_;
int val2_;
int val3_;
};
What you have above as a class myClass being defined with a constructor. That constructor takes one parameter, an int, that is used to direct-initialize the data member val1_. The data member val2_ is also direct-initialized to 13, while the data member val3_ is copy-initialized to 14 inside the constructor body.
Of course the difference can be seen as meaningless for these type of objects. However its significant for certain datatypes. Among them references and user defined classes that don't offer a default constructor. Consider:
Code:
class myClass {
public:
myClass() {
int x;
val1_ = x;
}
private:
int& val1_;
};
I bet by this time you already know why the above code will fail to compile. val1_ is a reference. It has to be initialized at the time it is being defined. When you write it's name in the private section of your class you are only declaring it. You are only introducing the name. You are not actually allocating space to it in the memory. That will happen when the constructor is ran (in other words when a real instance of that class is created).
At that time a value has to be given in order to initialize it. It wasn't. By the time the body of the constructor starts to get executed all your private data members have already been allocated in memory (they have been defined). But nowhere was your reference initialized. The compilerwill flag the error.
Ok, let's do it right...
Code:
class myClass {
public:
myClass(int x): val1_(x) {}
private:
int& val1_;
};
And this is the anti-climatic end to a long post. References data members can only be initialized from constructor arguments, public objects or other data members. Being this last one worth a post of its own.