Reputation: 45
I have two classes, with one on them having an object of the other as reference Member:
class myClass{
public:
myClass() { };
};
class mySecondClass {
public:
mySecondClass(myClass& reference)
{
myClassReference = reference; //doesn't get accepted by the compiler
};
myClass& myObjectReference;
};
I found out (thanks to Passing by reference to a constructor
), that mySecondClass(myClass& reference) : myObjectReference(reference){};
does the job.
But why can't I use myObjectReference = reference;
?
Upvotes: 1
Views: 94
Reputation: 311078
In the constructor
mySecondClass(myClass& reference)
{
myClassReference = reference; //doesn't get accepted by the compiler
};
there is used reference myClassReference
that shall be initialized when it is created. However the variable was not initialized. There is used the copy assignment operator.
In this constructor
mySecondClass(myClass& reference) : myObjectReference(reference){}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the reference is created and initialized in the mem-initializer list.
To make it more clear consider the following demonstrative program.
#include <iostream>
struct Int
{
Int() { std::cout << "Int()\n"; }
Int( int x ) : x( x ) { std::cout << "Int( " << x << " )\n"; }
Int & operator =( int x )
{
std::cout << "Int & operator =( " << x << " )\n";
this->x = x;
return *this;
}
int x;
};
struct A
{
A( int x )
{
this->value = x;
}
Int value;
};
struct B
{
B( int x ) : value( x ) {}
Int value;
};
int main()
{
A a( 10 );
std::cout << '\n';
B b( 10 );
return 0;
}
Its output is
Int()
Int & operator =( 10 )
Int( 10 )
That is when the body of the constructor A gets the control the data member was already created using the default constructor of the class Int. Within the body of the constructor there is used the assignment operator.
Opposite to the constructor of the class A the constructor of the class B created the data member in the mem-inkitializer list using the constructor of the class Int with a parameter.
So now imagine that you are using a reference in the class A. Then it is "default-initialized" that is it is not actually initialized by any valid object to which it shell refer. So in the body of the constructor you are trying to assign a value to an invalid reference that refers nowhere. So the compiler issues an error.
Upvotes: 2
Reputation: 16910
It's because { myClassReference = reference; }
is considered as an
assignment to something which is supposed to be already initialised.
The member initialisation list : member1{value1}, member2{value2}...
is intended to provide the initial value (nothing is supposed to
be valid before).
For the specific case of a reference, it's the same situation as
int i=4;
int &r=i; // the reference is initialised (alias for i)
r=5; // the reference itself is not changed but
// the referenced object (i) is assigned
Upvotes: 3