By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,837 Members | 1,681 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,837 IT Pros & Developers. It's quick & easy.

Weird reference declaration?

P: n/a
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
Jul 22 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
"Anon Email" <an********@fastmail.fm> wrote in message
news:83*************************@posting.google.co m
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)

Jul 22 '05 #2

P: n/a

"Anon Email" <an********@fastmail.fm> wrote in message
news:83*************************@posting.google.co m...
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
Jul 22 '05 #3

P: n/a
"Nick Hounsome" <nh***@blueyonder.co.uk> wrote in message
news:8W************@news-binary.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'.

$.02,
-Mike
Jul 22 '05 #4

P: n/a

"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:bN*****************@newsread2.news.pas.earthl ink.net...
"Nick Hounsome" <nh***@blueyonder.co.uk> wrote in message
news:8W************@news-binary.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.
$.02,
-Mike

Jul 22 '05 #5

P: n/a
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 = ...

(the latter referring to a r/o reg which reflects h/w status, and
therefore can change under you).
Jul 22 '05 #6

P: n/a

"red floyd" <no*****@here.dude> wrote in message
news:x0******************@newssvr25.news.prodigy.c om...
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.
(the latter referring to a r/o reg which reflects h/w status, and
therefore can change under you).

Jul 22 '05 #7

P: n/a
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);
}
Jul 22 '05 #8

P: n/a
"Anon Email" <an********@fastmail.fm> wrote in message
news:83*************************@posting.google.co m
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)


#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);
}

Jul 22 '05 #9

P: n/a
an********@fastmail.fm (Anon Email) wrote in message news:<83*************************@posting.google.c om>...
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]
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);
}

Jul 22 '05 #10

P: n/a
c++novice wrote:
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();

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.

class Calculator
{
public:
Calculator () : _done (false)
{
cout << "Calculator created\n";
}
bool Execute (Input & input)
{
cout << "Calculator::Execute\n";
return !_done;
}
IStack const & GetStack () const
This function promises to not change the Calculater
object it is called with.
{
_done = true;
But here you try to exactly to do that.
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
kb******@gascad.at
Jul 22 '05 #11

P: n/a
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
Jul 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.