On 25/05/2007, at 12:48 AM, Michael Chesterton wrote:
When passing an array as an argument to a function, say, print_foo,
where the function isn't meant to modify the array, it makes perfect
sense to me to make it a const.
The C++ FAQ Lite has a section devoted to const correctness:
http://www.parashift.com/c++-faq-lite/const-correctness.html
It's an invaluable resource to bookmark if you do any C++ coding.
But what about when passing structs, ints, bools, etc? If the function
doesn't need to modify them, what's the standard practice?
I guess an example. (hopefully if I've ERRORED, my intent is still
clear)
struct foo
{
int x;
int y;
};
void init(foo &p, const int x, const int y)
{
p.x = x;
p.y = y;
}
Do people do that in practice? Is it good practice?
Most people don't bother using const for function parameters that are
primitives (ints, bools, char, etc). I still do, since I think it's
good documentation: it indicates you never intend to modify it in the
function, and frees up your mental stack to track something else.
If you're passing a large structure to a function, the standard C++
idiom is to pass a const reference rather than pass the structure by
value, so instead of this:
void foo(my_large_structure_t bar);
do this:
void foo(const my_large_structure_t& bar);
Using a reference prevents a copy of the large structure, which can
be relatively expensive. Using a const reference means that you
can't change the original structure, so it gives more similar
semantics to pass-by-value. It also theoretically enables more
optimisation opportunities, although in practice it's not a big win.
You can also use const references for primitive types too (e.g. const
int& foo), but that's not done because it's generally a performance
loss, and it also looks weird :).
Personal opinion: I go so far as to declare all my local variables as
const, and will sometimes restructure code to ensure that const is
used on as many variables as possible. I actually wish that C++09
would have a compiler flag to enforce const being the default, and
that you'd have to put the keyword 'mutable' in front of variables
you want to change :). (My Haskell background is showing here...)
Using const heavily makes reading and grokking the code much easier,
IMHO.
There's two more issues with const. For pointers, you can have
"const Foo* p", meaning that the value of the p pointer can change,
but the value that p points to is const; "Foo* const p", which means
that the p pointer is const but that you can change the Foo value
that p points at; and "const Foo* const p", meaning both. "Foo*
const p" is similar in spirit to a reference, since you cannot
"reseat" the pointer. "const Foo* const p" is similar to a const&.
There's also const member functions, which means that the member
function cannot change the object's member variables. They're
usually used with accessors:
class Foo
{
public:
// Note the const qualifier after the function prototype below
int getX() const
{
return x;
}
void setX(const int newX)
{
x = newX;
}
private:
int x;
}
See the C++ FAQ lite for more information, it's really a superb
resource.
Oh yeah, and there's also const_iterators that you can use in place
of iterators (const_iterator it = map.begin(); ...).
--
% Andre Pang : trust.in.love.to.save <http://www.algorithm.com.au/>
_______________________________________________
coders mailing list
[email protected]
http://lists.slug.org.au/listinfo/coders