Initialize a Reference type class attribute

K

ken.carlino

Hi,

Can I use Reference type as my class attribute, like this? Or I have to
use pointers for class attribute?
class B;
class A {

public:
B& _b;
};


If yes, how can I init the class attribute?

I try this:

A::A(const B& b)
{
_b = b;
}

I get this error "error: uninitialized reference member "

I try this:
A::A (const B& b) :
_b(b)

{

}
I get this error "error: invalid initialization of reference of type "

or I have to use Pointers ?
 
B

Bob Hairgrove

Hi,

Can I use Reference type as my class attribute, like this? Or I have to
use pointers for class attribute?
class B;
class A {

public:
B& _b;
};


If yes, how can I init the class attribute?

I try this:

A::A(const B& b)
{
_b = b;
}

I get this error "error: uninitialized reference member "

I try this:
A::A (const B& b) :
_b(b)

{

}
I get this error "error: invalid initialization of reference of type "

or I have to use Pointers ?

Your B& member is non-const, therefore you cannot initialize it with a
const B&. The second try would have worked if you had declared your
constructor to take a B& and not a const B&.
 
K

ken.carlino

Thanks.
I thought by saying "A::A(const B& b) {...}", it means i can't change
what 'b' is pointing to, not b is pointing to a constant B.

this is kind of like when we overload operator, we do this:
const A operator* (const A& lhs, const A& rhs);

or it is totally different?

That is based on my understanding of item 21 "Use const whenever
possible" in effecitive C++.

thank you.
 
B

Bo Persson

Thanks.
I thought by saying "A::A(const B& b) {...}", it means i can't
change
what 'b' is pointing to, not b is pointing to a constant B.

But b isn't pointing, it is a reference to a B. :)

A reference is like another name for the original object.

What look like an assignment to _b,

_b = something();

is really an assignment to the object _b refers to. And if that object
is const, assigning it through _b would be totally wrong.
this is kind of like when we overload operator, we do this:
const A operator* (const A& lhs, const A& rhs);

or it is totally different?

It's similar, but different. :)

Consider how your A class is supposed to be used:

const B some_B;

A a = some_B;

Now a's member _b is an alias for some_B, which is const. Assigning

a._b = something();

would actually try to assign the value to some_B. Not allowed.

That is based on my understanding of item 21 "Use const whenever
possible" in effecitive C++.

Use it as much as possible, but not more than that.


Bo Persson
 
K

ken.carlino

A related question, why when we declare a copy constructor, we always
put "const in front of the reference"?
like this:

class Account {
public:
Account (const Account&);

}
 
T

Thomas Tutone

A related question, why when we declare a copy constructor, we always
put "const in front of the reference"?
like this:

class Account {
public:
Account (const Account&);

}

It's not required, but it's generally good practice if (as is usually
the case) the copy constructor does not modify the original object.
Take a look at the FAQ on this topic:

http://www.parashift.com/c++-faq-lite/const-correctness.html

Among other things, if you didn't include the const, the copy
constructor would not work on non-const objects, which could be a
significant issue.

std::auto_ptr<> is an example of a template class from the standard
library that uses a non-const copy constructor. And its behavior often
surprises people not previously familiar with it.

Best regards,

Tom
 
T

Thomas Tutone

Thomas said:
Among other things, if you didn't include the const, the copy
constructor would not work on non-const objects, which could be a
significant issue.

Oops - I meant the copy constructor would not work on _const_ objects.

Best regards,

Tom
 
K

ken.carlino

Thanks. That is what I understand too. "it's generally good practice if
(as is usually
the case) the copy constructor does not modify the original object. "

Back to my original quesiton, why I can't do this. It only works if I
remove the 'const' in the input parameter of the Constructor. I do not
modify the input parameter of the constructor, why I can't add 'const'
in the input parameter.

class B;
class A {

public:
B& _b;
};
A::A (const B& b) :
_b(b)

{

}
 
T

Thomas Tutone

Back to my original quesiton, why I can't do this. It only works if I
remove the 'const' in the input parameter of the Constructor. I do not
modify the input parameter of the constructor, why I can't add 'const'
in the input parameter.

class B;
class A {

public:
B& _b;
};
A::A (const B& b) :
_b(b)

{

}

Because _b is a reference to (i.e., an alias for) the passed argument.
That means if anyone makes any changes to _b, that is really a change
in the passed argument. So basically, you can make your class in two
different ways:

class A {
B& b_; // no const
public:
A(B& b) : b_(b) {} // no const
};

or

class A {
const B& b_; // note const
public:
A(const B& b) : b_(b) {} // note const
};

In other words, since it's a reference, const must appear in both
places or neither.

Best regards,

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,142
Messages
2,570,819
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top