What are constant references used for?

Started by
19 comments, last by ApochPiQ 9 years, 11 months ago
In C++, is there an actual usage for constant references, or is it there for completeness(and perhaps to add ambiguity.)?

I would simply use constant variable or a preprocessor substitution to a literal value.
Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.
Advertisement

Are you talking about c++?

A common usage is for function parameters when you want to avoid the overhead of copying the object, but still don't want the function to be able to modify the original.

A const reference is exactly what it says it is: the reference itself is always const and must be initialized to refer to a valid object, const means that the object can't be modified through the reference.

This is why its advisable to take parameters passing large objects that you don't intend to modify as a const reference -- even if the object itself is not const, passing by const reference ensures that the function can't modify the object. It helps enforce and documents the intended contract of the function. This principle need not be used in conjunction with function parameters though -- a const reference is useful any time you want to enforce immutability of a (potentially) mutable object, it just does so with a different name -- that of the reference.

A const reference can reference both const and non-const objects, but you can't take a non-const reference to a const object, so there's no backdoor to modifying a const object. At least not without further subversion of the type system.

throw table_exception("(? ???)? ? ???");

Read-only visibility into an object is also a common use case, i.e. returning a const reference from a function.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

A const reference can reference both const and non-const objects, but you can't take a non-const reference to a const object, so there's no backdoor to modifying a const object. At least not without further subversion of the type system.


It would be difficult to imagine modifying a literal like 1 or the address of the first character of "Hello". In C that is undefined behaviour if allowed(if I recall correctly).
Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.

Read-only visibility into an object is also a common use case, i.e. returning a const reference from a function.


Would it refer to anything? I mean, after the execution of the function, local variables with automatic block duration would be wiped out of memory, hence the reference returned by such hypothetical function would refer to garbage.
Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.

Literals aren't really a relevant consideration. Think of references as pointers to some location in memory that holds some value. That's essentially what they are; syntactic sugar on top of a pointer, with a few semantic bonuses to help the compiler understand what you're attempting to do and thereby do it efficiently, or tell you it can't be done and give a reasonable explanation as to why.

So if there's a chunk of memory that has a value, and you have a reference to that memory, then it wouldn't be that hard to imagine modifying that value. Marking the reference as const just helps to protect you from your own forgetfulness, so that you don't accidentally modify something that other pieces of code are assuming won't be modified naively.

Note that if you ever happen to pass a literal value to a function that has a const reference parameter, the literal itself isn't what the reference refers to. Instead, the literal gets copied/pushed onto the call stack as a function parameter, and thus that parameter is stored in memory and has an address. (There might be optimizations whereby the literal is instead copied directly into a register and never stored to memory, but this probably only ever happens if the compiler knows for certain that you never use the reference in a way that would depend on the parameter being in memory. In which case, the fact that the parameter is a const reference is in effect ignored by the compiler, since it didn't matter.)

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

Would it refer to anything? I mean, after the execution of the function, local variables with automatic block duration would be wiped out of memory, hence the reference returned by such hypothetical function would refer to garbage.

Local variables, yes. But member variables of a class that hasn't gone out of scope would persist.

Look at std::vector, the const versions of the [] operator or the at function return a const reference to the requested index.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

but this probably only ever happens if the compiler knows for certain that you never use the reference in a way that would depend on the parameter being in memory.


How wouldn't it? I mean, 5 is always going to be 5 and it is known at compile time.
Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.

5 and "hello" are literals.

int and std::string are variables.

int& and std::string& are reference variables.

It's mostly pointless to pass an int by const reference because it is so small, but it is very useful to pass a std::string by const reference. Passing a std::string by value means you have to copy it. Passing a std::vector<std::string> by value means every element in the vector will be copied.

It is very useful to be able to say, "I don't want to copy this variable, but I want to pass read-only access to it." - this means either a const reference or a const pointer. It serves a really useful purpose.

Example:


ByteBuffer lotsOfData = LoadFile("myfile.data");
 
DoSomethingWithTheData(lotsOfData);

I'd much rather 'DoSomethingWithTheData()' takes the buffer by const reference than copying all the bytes.

[Edit:] Ah, perhaps you are meaning Type & const, instead of const Type & ? Yeah, that's pointless (and I think invalid code). But const Type & is definitely valuable.

This topic is closed to new replies.

Advertisement