Dan
Dan

Reputation: 35453

Reference Member Required to be Const?

In this simple example, why do I need to make 'member' const in order to get this to compile?

struct ClassA
{
    ClassA(int integer) {}
};

struct ClassB
{
    ClassB(int integer):
        member(integer)
    {
    }

    const ClassA& member;
};

int main()
{
    ClassB* b = new ClassB(12);

    return 0;
}

Otherwise, I get this error:

error: invalid initialization of reference of type 'ClassA&' from expression of type 'int'

Upvotes: 4

Views: 265

Answers (4)

Jerry Coffin
Jerry Coffin

Reputation: 490138

You're create a temporary, and initializing the reference from that temporary. Just like usual, to bind to a temporary, a reference has to be const.

I'd have serious second thoughts about this. A class with a reference member is rarely useful. When it is useful, you generally want to start with some existing object and pass a reference to that object through to the member reference. When you do this, you need to be sure the referenced object exists for the entire lifetime of the object containing a reference, so the two are quite tightly coupled -- which you'd usually rather avoid.

Upvotes: 0

JaredPar
JaredPar

Reputation: 754745

The reason why is that what's actually happening here is you're using an implicit conversion from int to ClassA in the initialization of member. In expanded form it is actually doing the following

member(ClassA(integer))

This means that the ClassA instance is a temporary. It's not legal to have a reference to a temporary variable only a const reference hence you get the compiler error.

The easiest fix is to remove the & modifier on member and make it just of type ClassA

ClassA member;

Additionally it's a good practice to put explicit in front of the ClassA constructor to avoid the silent implicit conversion.

explicit ClassA(int integer){}

Upvotes: 10

CharlesB
CharlesB

Reputation: 90316

ClassA is a reference member of ClassB, so it must be instantiated with an instance of ClassA.

Upvotes: 0

Tyler McHenry
Tyler McHenry

Reputation: 76660

Because you are trying to store a reference to a temporary object, and you may only store constant references to temporaries.

When you try to initialize the member reference of type ClassA& with the integer parameter of type int, the implicit conversion constructor ClassA::ClassA(int integer) is inovked to produce an unnamed temporary object of type ClassA from the integer variable. That unnamed temporary object is then used to initialize the reference member, creating a reference-to-temporary, which must be const.

I question your design here. If you're trying to initialize member with data passed by value to the ClassB constructor, having member be a reference is probably not the right thing to do. Why do you think member ought to be a reference and not just an object?

Upvotes: 4

Related Questions