Weird reference declaration?

A

Anon Email

Hey people,

This looks really weird. I can't make sense of it. Is this a mistake?
Can anyone help?


IStack const & GetStack () const;


Cheers,

Deets
 
J

John Carson

Anon Email said:
Hey people,

This looks really weird. I can't make sense of it. Is this a mistake?
Can anyone help?


IStack const & GetStack () const;


Cheers,

Deets



This is the declaration of a member function called GetStack. It returns a
const reference to an IStack object. The final const means that calling
GetStack does not change the class object from which it is called. Only
member functions declared const can be called from a const class object.
 
N

Nick Hounsome

Anon Email said:
Hey people,

This looks really weird. I can't make sense of it. Is this a mistake?
Can anyone help?


IStack const & GetStack () const;

This is exactly the same as
const IStack& GetStack() const

If that helps - I find the current trend in this group to put the const
after the type as most
confusing and unwelcome since it is counter to all historical C usage that I
have ever come across.

If you don't understand my rewrite then you need to read a C++ book first
because it is
really basic stuff.

I slightly more useful example might be

IStack const* stack;
const IStack* stack;
IStack* const stack;

Where the first two define a changeable pointer to a constant IStack but the
last one
defines a constant pointer to an changeable IStack.
The equivalent as a method doesn't acheive much because returning a constant
pointer
has no effect on anything (other than template functuion issues).

Which returns a constant pointer
 
M

Mike Wahler

[snip]
I slightly more useful example might be

IStack const* stack;
const IStack* stack;
IStack* const stack;

Where the first two define a changeable pointer to a constant IStack but the
last one
defines a constant pointer to an changeable IStack.

And imo the syntax of that last one is what causes some folks
to use the first one: in the interest of 'consistency'.

$.02,
-Mike
 
N

Nick Hounsome

Mike Wahler said:
[snip]
I slightly more useful example might be

IStack const* stack;
const IStack* stack;
IStack* const stack;

Where the first two define a changeable pointer to a constant IStack but the
last one
defines a constant pointer to an changeable IStack.

And imo the syntax of that last one is what causes some folks
to use the first one: in the interest of 'consistency'.

And it is usually down to trying to hard to stop people doing stuff when it
isn't really necessary.

Personally I have never come across a compelling need for (explicit) const
pointers and
many reasons not to use them. The same goes for reference members.
 
R

red floyd

Nick said:
And it is usually down to trying to hard to stop people doing stuff when it
isn't really necessary.

Personally I have never come across a compelling need for (explicit) const
pointers and
many reasons not to use them. The same goes for reference members.

Const pointers are useful in embedded programming... e.g.:

unsigned long *const SOME_HW_REG = reinterpret_cast<unsigned long
*>(0xFFFF0000);

or my personal favorite:

const volatile unsigned long *const SOME_RO_HW_REG = ...

(the latter referring to a r/o reg which reflects h/w status, and
therefore can change under you).
 
N

Nick Hounsome

red floyd said:
Const pointers are useful in embedded programming... e.g.:

unsigned long *const SOME_HW_REG = reinterpret_cast<unsigned long
*>(0xFFFF0000);

or my personal favorite:

const volatile unsigned long *const SOME_RO_HW_REG = ...

I think I'd rather go for a reference there.
I also think that there is supposed to be some standardisation stuff going
on for embedded - it all happens with templates
apparently.
 
A

Anon Email

Hi people,

IStack const & GetStack () const;

I think I understand this now. Kind of. Thanks to all for your
insights. Let me try to clarify:

The GetStack() function returns a constant reference to an IStack
object. Since it is declared constant (i.e., the second "const" in the
declaration), it cannot change the class object from which it is
called.

Now, the reason I was puzzled by this is because the following code
(from a book I'm reading - I'm learning C++) does not compile unless
the second "const" is removed. So perhaps the book code is wrong? The
compiler doesn't like the assignment "_done = true;" in the context of
a const function. But shouldn't this be OK? I mean, it's only changing
an internal variable (to the same class) - i.e., it's not "changing
the class object from which it's called."

Any further help appreciated.

Cheers,

Deets


#include <iostream>
using std::cout;
using std::endl;

class IStack {};

class StackSeq
{
public:
StackSeq (IStack const & stack ): _stack (stack), _done (false)
{
cout << "Stack sequencer created\n";
}
bool AtEnd () const { return _done; }
void Advance () { _done = true; }
int GetNum () const { return 13; }
private:
IStack const & _stack;
bool _done;
};

class Input
{
public:
Input ()
{
cout << "Input created\n";
}
};

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator created\n";
}
bool Execute (Input & input)
{
cout << "Calculator::Execute\n";
return !_done;
}
IStack const & GetStack () const
{
_done = true;
return _stack;
}
private:
IStack _stack;
bool _done;
};

int main ()
{
Calculator TheCalculator;
bool status;
do
{
// Prompt for input
cout << "> ";
Input input;
status = TheCalculator.Execute (input);
if ( status )
{
for (StackSeq seq (TheCalculator.GetStack ());
!seq.AtEnd ();
seq.Advance () )
{
cout << " " << seq.GetNum () << endl;
}
}
} while (status);
}
 
J

John Carson

Anon Email said:
Hi people,

IStack const & GetStack () const;

I think I understand this now. Kind of. Thanks to all for your
insights. Let me try to clarify:

The GetStack() function returns a constant reference to an IStack
object. Since it is declared constant (i.e., the second "const" in the
declaration), it cannot change the class object from which it is
called.

Now, the reason I was puzzled by this is because the following code
(from a book I'm reading - I'm learning C++) does not compile unless
the second "const" is removed. So perhaps the book code is wrong? The
compiler doesn't like the assignment "_done = true;" in the context of
a const function. But shouldn't this be OK? I mean, it's only changing
an internal variable (to the same class) - i.e., it's not "changing
the class object from which it's called."


The two things are synonymous. You have a Calculator object called, say,
calc. Using that object, you make the call:

IStack const & istack = calc.GetStack();

This changes the _done variable within calc, i.e., it changes the class
object from which it is called.
 
C

c++novice

Hi people,

IStack const & GetStack () const;

I think I understand this now. Kind of. Thanks to all for your
insights. Let me try to clarify:

The GetStack() function returns a constant reference to an IStack

NO, it does not return a constant refernece, it returns a reference to
constant IStack.
And yes there is nothing like constant reference. since references are
always const. u can not reset them.
read FAQ Lite [18.8]
 
K

Karl Heinz Buchegger

Not 'from which' it is called.
*For which* it is called. The object you specify in the call
to this function, eg.

Calculator MyCalc;

MyCalc.GetStack();

It is attempting to change the class object.
But the const function has promised to not to do this.

This function promises to not change the Calculater
object it is called with.

But here you try to exactly to do that.

If your main function looks eg. like this:

int main()
{
const Calculator MyCalc;

// here you have an object called MyCalc. You defined
// it to be const. This means that this object will
// not change during its whole lifetime.
//
// But now, you call

MyCalc.GetStack();

// you can do that. Function GetStack is marked as const,
// hence it will not change the MyCalc object in any way.
// And since this is so, it is legal to call that function
// on an object which is marked to not to change.
// But wait: inside GetStack the member variable _done
// if MyCalc gets changed! So the object has changed!
// But how can this be: GetStack has promised to not
// change MyCalc! But now MyCalc *has* changed.

That's why the copmiler will not allow you to compile the
function GetStack as it is now. If you declare that function
to be const, you are not allowed to change oridnary member
variables.
 
A

Anon Email

-------------

To c++novice:
NO, it does not return a constant refernece, it returns a reference to
constant IStack.
And yes there is nothing like constant reference. since references are
always const. u can not reset them.
read FAQ Lite [18.8]

Sorry for the confusing use of terminology. The only reason I said
"constant reference" is because the book says so! Here is the quote:

"The constructor of StackSeq is called with a reference to a const
IStack. One of the data members is also a reference to a const IStack.
A const reference cannot be used to change the object it refers to."

"A constant reference..."? As you say, all references are constant. I
just assumed that it was a common for references that return constants
to be referred to as "constant references". Actually, I bet that they
ARE commonly referred to in this manner, even though it's wrong
terminology.

---------

Thanks to Karl and everyone else. That makes sense now. The book was
wrong.

Cheers,

Deets
 
A

Anon Email

Hi people,

Actually, I have another question about this code. Let me refer to the
following section of code first:

1)
for (StackSeq seq (TheCalculator.GetStack ());

Calling TheCalculator.GetStack () returns a reference to a const
IStack, right? This then gets passed as an argument to the seq object,
correct?

2)
status = TheCalculator.Execute (input);

Here you are passing an object (input) to a function awaiting a
reference argument.

So:

1) Passing a reference to a function awaiting a reference argument.
2) Passing an object to a function awaiting a reference argument.

I was of the understanding that in 1) the function would then see what
was passed to it as being a pointer? I accept that in 2) the passed
"object" is seen as a reference. But does the same happen in 1)?

Cheers,

Deets
 

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,160
Messages
2,570,889
Members
47,420
Latest member
ZitaVos505

Latest Threads

Top