C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Weird reference declaration?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Anon Email
Guest





PostPosted: Sun Jan 25, 2004 8:29 am    Post subject: Weird reference declaration? Reply with quote



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
Back to top
John Carson
Guest





PostPosted: Sun Jan 25, 2004 8:38 am    Post subject: Re: Weird reference declaration? Reply with quote



"Anon Email" <anonemail1 (AT) fastmail (DOT) fm> wrote

Quote:
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.


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


Back to top
Nick Hounsome
Guest





PostPosted: Sun Jan 25, 2004 7:37 pm    Post subject: Re: Weird reference declaration? Reply with quote




"Anon Email" <anonemail1 (AT) fastmail (DOT) fm> wrote

Quote:
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



Back to top
Mike Wahler
Guest





PostPosted: Sun Jan 25, 2004 9:44 pm    Post subject: Re: Weird reference declaration? Reply with quote

"Nick Hounsome" <nh002 (AT) blueyonder (DOT) co.uk> wrote


[snip]

Quote:
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



Back to top
Nick Hounsome
Guest





PostPosted: Mon Jan 26, 2004 5:06 pm    Post subject: Re: Weird reference declaration? Reply with quote


"Mike Wahler" <mkwahler (AT) mkwahler (DOT) net> wrote

Quote:
"Nick Hounsome" <nh002 (AT) blueyonder (DOT) co.uk> wrote in message
news:8WUQb.98$GQ1.3 (AT) news-binary (DOT) blueyonder.co.uk...

[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.

Quote:
$.02,
-Mike





Back to top
red floyd
Guest





PostPosted: Mon Jan 26, 2004 5:21 pm    Post subject: Re: Weird reference declaration? Reply with quote

Nick Hounsome wrote:

Quote:
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).

Back to top
Nick Hounsome
Guest





PostPosted: Mon Jan 26, 2004 9:56 pm    Post subject: Re: Weird reference declaration? Reply with quote


"red floyd" <no.spam (AT) here (DOT) dude> wrote

Quote:
Nick Hounsome wrote:

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 = ...


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.

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



Back to top
Anon Email
Guest





PostPosted: Wed Jan 28, 2004 3:01 am    Post subject: Re: Weird reference declaration? Reply with quote

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 createdn";
}
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 createdn";
}
};

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator createdn";
}
bool Execute (Input & input)
{
cout << "Calculator::Executen";
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);
}
Back to top
John Carson
Guest





PostPosted: Wed Jan 28, 2004 9:47 am    Post subject: Re: Weird reference declaration? Reply with quote

"Anon Email" <anonemail1 (AT) fastmail (DOT) fm> wrote

Quote:
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.


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


Quote:

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

class IStack {};

class StackSeq
{
public:
StackSeq (IStack const & stack ): _stack (stack), _done (false)
{
cout << "Stack sequencer createdn";
}
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 createdn";
}
};

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator createdn";
}
bool Execute (Input & input)
{
cout << "Calculator::Executen";
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);
}



Back to top
c++novice
Guest





PostPosted: Wed Jan 28, 2004 5:27 pm    Post subject: Re: Weird reference declaration? Reply with quote

[email]anonemail1 (AT) fastmail (DOT) fm[/email] (Anon Email) wrote in message news:<83b3ca3.0401271901.7a02e0d0 (AT) posting (DOT) google.com>...
Quote:
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]

Quote:
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 createdn";
}
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 createdn";
}
};

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator createdn";
}
bool Execute (Input & input)
{
cout << "Calculator::Executen";
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);
}

Back to top
Karl Heinz Buchegger
Guest





PostPosted: Wed Jan 28, 2004 5:44 pm    Post subject: Re: Weird reference declaration? Reply with quote

c++novice wrote:
Quote:

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.

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();

Quote:

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."

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

Quote:

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator createdn";
}
bool Execute (Input & input)
{
cout << "Calculator::Executen";
return !_done;
}
IStack const & GetStack () const

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

Quote:
{
_done = true;

But here you try to exactly to do that.

Quote:
return _stack;
}

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
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
Anon Email
Guest





PostPosted: Thu Jan 29, 2004 1:21 am    Post subject: Re: Weird reference declaration? Reply with quote

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

To c++novice:

Quote:
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

Back to top
Anon Email
Guest





PostPosted: Wed Feb 04, 2004 5:53 am    Post subject: Re: Weird reference declaration? Reply with quote

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
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.