Connecting Tech Pros Worldwide Forums | Help | Site Map

Weird reference declaration?

Anon Email
Guest
 
Posts: n/a
#1: Jul 22 '05
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

John Carson
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Weird reference declaration?


"Anon Email" <anonemail1@fastmail.fm> wrote in message
news:83b3ca3.0401250029.1b169583@posting.google.co m[color=blue]
> 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[/color]



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.


--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Nick Hounsome
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Weird reference declaration?



"Anon Email" <anonemail1@fastmail.fm> wrote in message
news:83b3ca3.0401250029.1b169583@posting.google.co m...[color=blue]
> Hey people,
>
> This looks really weird. I can't make sense of it. Is this a mistake?
> Can anyone help?
>
>
> IStack const & GetStack () const;[/color]

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


Mike Wahler
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Weird reference declaration?


"Nick Hounsome" <nh002@blueyonder.co.uk> wrote in message
news:8WUQb.98$GQ1.3@news-binary.blueyonder.co.uk...

[snip]
[color=blue]
> 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[/color]
the[color=blue]
> last one
> defines a constant pointer to an changeable IStack.[/color]

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


Nick Hounsome
Guest
 
Posts: n/a
#5: Jul 22 '05

re: Weird reference declaration?



"Mike Wahler" <mkwahler@mkwahler.net> wrote in message
news:bNWQb.26372$1e.2881@newsread2.news.pas.earthl ink.net...[color=blue]
> "Nick Hounsome" <nh002@blueyonder.co.uk> wrote in message
> news:8WUQb.98$GQ1.3@news-binary.blueyonder.co.uk...
>
> [snip]
>[color=green]
> > 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[/color]
> the[color=green]
> > last one
> > defines a constant pointer to an changeable IStack.[/color]
>
> And imo the syntax of that last one is what causes some folks
> to use the first one: in the interest of 'consistency'.
>[/color]

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.
[color=blue]
> $.02,
> -Mike
>
>[/color]


red floyd
Guest
 
Posts: n/a
#6: Jul 22 '05

re: Weird reference declaration?


Nick Hounsome wrote:
[color=blue]
> 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.[/color]

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).
Nick Hounsome
Guest
 
Posts: n/a
#7: Jul 22 '05

re: Weird reference declaration?



"red floyd" <no.spam@here.dude> wrote in message
news:x0cRb.17437$Bf7.6568@newssvr25.news.prodigy.c om...[color=blue]
> Nick Hounsome wrote:
>[color=green]
> > And it is usually down to trying to hard to stop people doing stuff when[/color][/color]
it[color=blue][color=green]
> > isn't really necessary.
> >
> > Personally I have never come across a compelling need for (explicit)[/color][/color]
const[color=blue][color=green]
> > pointers and
> > many reasons not to use them. The same goes for reference members.[/color]
>
> 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 = ...
>[/color]

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.
[color=blue]
> (the latter referring to a r/o reg which reflects h/w status, and
> therefore can change under you).[/color]


Anon Email
Guest
 
Posts: n/a
#8: Jul 22 '05

re: Weird reference declaration?


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);
}
John Carson
Guest
 
Posts: n/a
#9: Jul 22 '05

re: Weird reference declaration?


"Anon Email" <anonemail1@fastmail.fm> wrote in message
news:83b3ca3.0401271901.7a02e0d0@posting.google.co m[color=blue]
> 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."
>[/color]


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.


--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

[color=blue]
>
> #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);
> }[/color]


c++novice
Guest
 
Posts: n/a
#10: Jul 22 '05

re: Weird reference declaration?


anonemail1@fastmail.fm (Anon Email) wrote in message news:<83b3ca3.0401271901.7a02e0d0@posting.google.c om>...[color=blue]
> 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[/color]

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]
[color=blue]
> 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);
> }[/color]
Karl Heinz Buchegger
Guest
 
Posts: n/a
#11: Jul 22 '05

re: Weird reference declaration?


c++novice wrote:[color=blue]
>[color=green]
> > 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.[/color][/color]

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();
[color=blue][color=green]
> >
> > 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."[/color][/color]

It is attempting to change the class object.
But the const function has promised to not to do this.
[color=blue][color=green]
> >
> > class Calculator
> > {
> > public:
> > Calculator () : _done (false)
> > {
> > cout << "Calculator created\n";
> > }
> > bool Execute (Input & input)
> > {
> > cout << "Calculator::Execute\n";
> > return !_done;
> > }
> > IStack const & GetStack () const[/color][/color]

This function promises to not change the Calculater
object it is called with.
[color=blue][color=green]
> > {
> > _done = true;[/color][/color]

But here you try to exactly to do that.
[color=blue][color=green]
> > return _stack;
> > }[/color][/color]

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.

--
Karl Heinz Buchegger
kbuchegg@gascad.at
Anon Email
Guest
 
Posts: n/a
#12: Jul 22 '05

re: Weird reference declaration?


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
Closed Thread