# C++ Workshop - Week 8-ish (Ch. 9)

This topic is 3533 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Chapter 9 – Exploiting References

Introduction Jeromy has had a couple issues with his computer and has been absent for a bit, so I'll pitch in with the next weeks thread. You've had a couple week break to absorb and practice with pointers, so hopefully this week will be a bit easier. Pointers have many uses in modern programming and can make very efficient code. References are a new addition to c++ that have some of the same advantages as pointers, but allow for an easier syntax. If you have a good grasp on pointers (which hopefully you do after the last chapter) references should not be too complicated to grasp. For Tutors Please remember to use OPINION and WARNING tags whenever applicable. As well, feel free to post your own insights, and review questions or exercises beginning Wednesday or Thursday. Outline of the Reading - Chapter 9
1. What is a Reference?
2. Using the Address-of operator (&) on references?
3. Referencing Objects
4. Null Pointers and Null References
5. Passing Function Arguments by Reference
6. Understanding Function Headers and Prototypes
7. Returning Multiple Values
8. Passing References for Efficiency
9. Knowing When to Use References vs. Pointers
10. Mixing References and Pointers
11. Returning Out-of-Scope Object References
12. Pointer, Pointer, Who Has the Pointer
Additional Resources None... Weekly Errata None...

## Good Luck!

##### Share on other sites
Heya All!

Sorry its taken me so long to get back to you guys. My computer melted a few weeks ago, and I've been trying to get back online since then. With my 1 mo. baby at home I cant get out much.

References are rather easy, and are a logical follow-through from pointers, so we'll just donate a half of a week to it so we can get back on schedule. I will try and post some quizzes, etc...over the next few days to help people get back in the mood.

Also, the first project will be posted on Monday, and will be running until the 15th of September, so be looking for that.

Cheers!

##### Share on other sites
A small point which is about consistency in the book. I don't know if this problem is related to different linkers/compilers:

On page 256, in the NOTE section, it states that there must be a space before the reference operator but the space following the reference operator is optional.

In question 6 of the quiz on page 287, it asks which of a, b and c is correct and the answer is given that all are acceptable.

I've played around with line 9 of listing 9.1, varying the spacing before and after the reference operator and it compiles/runs correctly whether it's int&rSomeRef, int &rSomeRef or int & rSomeRef. I use MSVC++ Express Edition.

Is the comment in the NOTE section wrong, or does this depend upon which software is used to link/compile?

##### Share on other sites
Though I can't claim that there are no compilers that don't handle it correctly, I am fairly confident in my claim that the standard says the space doesn't matter. (The note is wrong.)

Or the note may have actually been refering to the address of operator, and comparing this new usage to the one you learned in the last chapter. Read that note again, and let us know.

##### Share on other sites
The note says:

"Note that the reference operator (&) is the same symbol as the one used for the address-of operator. These are not the same operators, however, although clearly they are related.

The space before the reference operator is required; the space between the reference operator and the name of the reference variable is optional. Thus

int &rSomeRef = someInt; // ok
int & rSomeRef = someInt; // ok"

It appears that the note is wrong.

##### Share on other sites
int& rSomeRef = someInt; // also ok and in fact preferred by many

It's not possible to use the address-of operator in the type section of a declaration/definition, so there's no ambiguity with address-of.

##### Share on other sites
Indeed, the areas where the two operators appear are mutually exclusive. The & (reference) operator isn't actually an operator; it's a type-modifier, not unlike 'const' or 'volatile', and it can appear only in a declaration. The & (address-of) operator can appear only in a statement. This relationship is the same one shared between the * (pointer) type modifier and * (dereference) operator.

& (binary and) and * (multiplication) are both binary operators, and are thus differentiated from & (address-of) and * (dereference) as well.

For that matter; the only operator that can be used in a declaration is :: (scope-resolution) anyway. I think. I'm not going to put money on that statement. :)

##### Share on other sites
I justed wanted to thank everyone on the workshop. tutors and students included. I've learnt a lot here and although I havent posted yet I have been following closely. This had been a valuable source of info for me for what we have learnt up to this point and I consider myself getting old at 33 I'm still enjoying learning (J/K about the age thing, my parents keep calling me telling me I'm too old for games ;) ). Its been a reresher for me as I did learn c++ at uni but have never practiced it so forgot all about it. (I've been programming in C#...)

I believe I can make a very simple game which i intent to post shortly using the things we have currently learnt :) Keep up the good work and I look forward to continued reading.

##### Share on other sites
Greetings All!

Yeah, ok, so I know I'm WAAAAY behind on quizzes, but I've been busy with work and the new baby. And I'm actually rather surprised that no one else following the workshop bothered to create a quiz. At any rate, I finally got caught up. So....

It's once again QUIZ TIME!!! That's right, listed below are a set of quiz questions to help you test your knowledge and understanding of the material contained in chapters 9.

In addition to the questions and exercises below, make sure that as you're reading the book you enter the examples into your compiler, build the program, and run the executable. I know this is a time consuming process, but the repeat use of keywords, syntax, and semantics will help ingrain the information into your long-term memory. My advice is to create a simple "driver" project with a function main. As you read, enter the examples into function main, test it, and then erase it for use again in the next example.

I will create an answer thread for these questions immediately, so that people will have a chance to get the answers more quickly.

Chapter 9 Quiz

1. What is a reference?
2. What is returned if you try and get the address of a reference?
3. Can references be reassigned?
4. Can you create a reference to a class?
5. Is it possible to have null references?
6. What happens when a function prototype requests a reference.
7. How does the client (the caller) of a function know that the function uses references? (where can the client look)
8. What’s one method of allowing a function to “return” more than 1 value.
9. What benefits are there for using const references as parameters to functions rather than allowing the compiler to make copies of the objects? When is this most useful?
10. According to the text, when is the best time to use references? When is the best time to use pointers?
11. What is the primary thing to be careful of when returning references from a function?
12. According to the author, is it a good idea to allocate memory within a function, if the primary purpose is to return the newly allocated object back to the caller? If not, what’s an alternate solution?

##### Share on other sites
[EDIT: Question posted in programming forums]

[This has some to do with referencing]
I have mulled this topic around in my head some, and I have yet to figure it out: What are the specifics of returning an object by a function (non-reference)?

The reason why I question/ask this is that I have written a string class (for practice, not meant to be better than STL's), and I have been confused as to how to create an efficient concatenation method.
I have this code:
class string { ... string& operator+=(const string &x) { ... } //With overloads for 'char' and 'char*'};string operator+(const string &lhs,const string &rhs) { string temp(lhs); return temp+=rhs;}

However, I question it's efficiency. I feel as though I'm copying strings more than needed.
The contextual question is: Is the function returning 'temp', or is it returning a string copying temp?
[Following questions assume latter is true] How could I get rid of this excess copying? Is there a way to access the return variable directly? [Iffy, I know] Would inline-ing 'operator+' do anything, or would it still copy again?

NOTE: I know that this does not incur enough processing to relatively slow anything down, but I would be more at ease if there was something more I could do.

[Edited by - deadimp on November 17, 2006 7:06:13 PM]

##### Share on other sites
My apologies for posting the answers to the Quiz here, but, I have searched for the correct thread and apparantly, it was never created.

I searched under jwalsh his name, I tried googling, no avail.

Chapter 9.

1) What is a reference?
A) A reference is an alias; when you create a reference, you initialize it with the name of another object, the target. From that moment on, the reference acts as an alternative name for the target, and anything you do to the reference is really done to the target.

2) What is returned if you try and get the address of a reference?
A) It returns the address of its target.

3) Can references be reassigned?
A) No, references are ALLWAYS aliases for their target.

4) Can you create a reference to a class?
A) No, you create a reference to an object from a class, not to the class itself.

5) Is it possible to have null references?
A) Yes, the reason for this is that C++ needs to be usable for device drivers, embedded systems, and real-time systems that can reach directly into the hardware, the ability to reference specific addresses is valuebale and required. For this reason, most compilers support a null or numeric initialization of a reference without to much complaint, crashing only if you try to use the object in some way when that reference would be invalid.

Taking advantage of this in normal programming, however, is still not a good idea. When you move your pogram to another machine or compiler, mysterious bugs might develop if you have null references. In short, DON'T USE THEM !!!

6) What happens when a function prototype requests a reference?
A) Then the address of the original object is put on the stack, not the entire object.

7) How does the client (the caller) of a function know that the function uses references?(where can the client look)
A) By examining the parameters declared in the prototype, the client can look these up in the header-file(s) which tells the client all that is needed to know; it acts as the interface to the class or function.

8) What's one method of allowing a function to "return" more than 1 value?
A) One way to solve this is to pass two objects into the function, by reference.

9) What benefits are there for using const references as parameters to functions rather than allowing the compiler to make copies of the objects? When is this most useful?
A) Each time you pass an object into a function by value, a copy of the object is made. Each time you return an object from a function by value, another copy is made. Seeing as these objects are copied onto the stack, it not only takes time to do so, it also uses more memory then using references or pointers. For small objects, such as built-in integer values, this is trivial cost. However, with larger, user-created objects, the cost is greater. The size of a user-created object on the stack is the sum of each of its member variables. These in turn, can each be user-created objects, and passing such a massive structure by copying it onto the stack can be very expensive in performance and memory consumption.

10) According to the text, when is the best time to use references? When is the best time to use pointers?
A) Use references whenever possible, use pointers when you have to be able to create a NULL pointer or when you have to be able to reassign it to another object.

11) What is the primary thing to be careful of when returning references from a function?
A) You have to make sure that the returned reference won't go out of scope once the function terminates. This would create a reference pointing to nothing.

12) According to the author, is it a good idea to allocate memory within a function, if the primary purpose is to return the newly allocated object back to the caller? If not, what's an alternate solution?
A) No, according to the author, it is not a good idea, there are three alternative solutions to this in his mind:
1. Declare an object in the calling function and return that object by value from the function.
2. Declare an object on the free store in the function, and have that function return a pointer to that memory to the calling function.
3. Most suitable solution would be to declare the object in the calling function and then to pass it to the function by reference.

##### Share on other sites
Quote:
 5) Is it possible to have null references?A) Yes, the reason for this is that C++ needs to be usable for device drivers, embedded systems, and real-time systems that can reach directly into the hardware, the ability to reference specific addresses is valuebale and required. For this reason, most compilers support a null or numeric initialization of a reference without to much complaint, crashing only if you try to use the object in some way when that reference would be invalid.

No. Any attempt to create a "null reference" involves undefined behaviour. As you allude in a later answer, if one needs the concept of a NULL reference, use a pointer instead. No compilers support null or numeric initialisation of references.

Exception: const reference parameters can be initialised like this, but it acts like an unnamed temporary. For example you can call a function foo( const int &i ) using an integer literal, foo(42). This functions as you expect. This only applies to const references however.

Quote:
 Taking advantage of this in normal programming, however, is still not a good idea. When you move your pogram to another machine or compiler, mysterious bugs might develop if you have null references. In short, DON'T USE THEM !!!

Or even running the program again, or changing compiler version.

Quote:
 6) What happens when a function prototype requests a reference?A) Then the address of the original object is put on the stack, not the entire object.

While you can think of it like this, don't. Although many reference concepts apply to pointers, references are not pointers. In practise compilers will probably implement references with machine code pointers, we are at a higher level than that. We say instead that the variable is not copying but instead aliased directly through the reference parameter.

Quote:
 12) According to the author, is it a good idea to allocate memory within a function, if the primary purpose is to return the newly allocated object back to the caller? If not, what's an alternate solution?A) No, according to the author, it is not a good idea, there are three alternative solutions to this in his mind:1. Declare an object in the calling function and return that object by value from the function.2. Declare an object on the free store in the function, and have that function return a pointer to that memory to the calling function.3. Most suitable solution would be to declare the object in the calling function and then to pass it to the function by reference.

2) is the solution you are trying to avoid [smile]

Another option is to return the object in a smart pointer, such as std::auto_ptr or (preferably) boost::shared_ptr. This way there is no chance that the caller will forget to deallocate the memory.

##### Share on other sites
Original post by rip-off
Quote:
 5) Is it possible to have null references?No. Any attempt to create a "null reference" involves undefined behaviour. As you allude in a later answer, if one needs the concept of a NULL reference, use a pointer instead. No compilers support null or numeric initialisation of references.

Well, I thought that was the case, but since the book mentioned the answer I gave, I thought it was important to add it. Understand that you never use them, but, seeing as the book mentioned it, it must have it's uses.

Quote:
 6) What happens when a function prototype requests a reference?A) Then the address of the original object is put on the stack, not the entire object.While you can think of it like this, don't. Although many reference concepts apply to pointers, references are not pointers. In practise compilers will probably implement references with machine code pointers, we are at a higher level than that. We say instead that the variable is not copying but instead aliased directly through the reference parameter.

I understand that it is aliased, but, that does mean that the alias address is put on the stack, and not the whole object to which the reference aliases right?

Quote:
 12) According to the author, is it a good idea to allocate memory within a function, if the primary purpose is to return the newly allocated object back to the caller? If not, what's an alternate solution?A) 2. Declare an object on the free store in the function, and have that function return a pointer to that memory to the calling function.2) is the solution you are trying to avoid [smile]

Hmm, strange, because number two was mentioned in the book as one of the solutions, though not the correct solution to choose.

You are using memory on the heap, which stays available after the functions scope ends, why couldn't I use this pointer on the heap then to return it to the calling function and delete it there seeing it still exists after the scope of the function?

Thanks for the help rip-off, hope you understand my answers to your replies.

##### Share on other sites
Quote:
 Well, I thought that was the case, but since the book mentioned the answer I gave, I thought it was important to add it. Understand that you never use them, but, seeing as the book mentioned it, it must have it's uses.

I do not have a copy of the book, but when talking about C++ references you must understand that there is no way to create a "null reference" in the C++ language. However, and this is a terminology conflict, the term reference is a generic one and can be used in any situation where you use can use more than one variable to "refer" to a single instance in memory. In C (which has no C++ reference type modifier) we can only use pointers to get referencing. Java uses object references for all non primitive data. We must distinguish where your book is talking about C++ references as opposed to "General programming" references.

When talking about the programming technique "referencing" (available in many languages), the concept of a null reference is ok. In C and C++ you would use a NULL pointer. In Java a null object reference (null is a keyword in Java). In Lisp nil, in Lua nil, etc.

But back to the C++ type modifier '&' (not operator &), which signifies a C++ reference. A C++ reference cannot be "null", as a reference always needs to alias a valid object, and thus cannot have a "null" state.

Some people take advantage of the fact that C++ references are commonly implemented by compilers as pointers to simulate a "null reference". They come up with code like this:
int &null_reference = *((int *)0);

But by derefencing a NULL pointer, they invoke undefined behaviour. You cannot abuse the language to create something which the language forbids and expect it to work. This is why I stated that:
Quote:
 Original post by: me :)Although many reference concepts apply to pointers, references are not pointers.

Quote:
 I understand that it is aliased, but, that does mean that the alias address is put on the stack, and not the whole object to which the reference aliases right?

In practise, yes. But you must not think of C++ references as "pointers" or "addresses". A machine address can have a null state, but a C++ reference cannot. It is the compilers job to figure out how to implement the C++ concept of references and map them to something the machine can understand. You are insulated by a layer of C++ (thin as such a layer is).

Quote:
 Hmm, strange, because number two was mentioned in the book as one of the solutions, though not the correct solution to choose.You are using memory on the heap, which stays available after the functions scope ends, why couldn't I use this pointer on the heap then to return it to the calling function and delete it there seeing it still exists after the scope of the function?

Well, maybe I misread the function's original description. I read a function who's "primary purpose is to return the newly allocated object back to the caller" as a function that declares "an object on the free store in the function" and which returns "a pointer to that memory to the calling function.". I assumed that allocate here doesn't mean to use stack objects (as one rarely mentions "allocation" when speaking of automatic or stack objects since the compiler allocates them for us).

Is the function we are trying to rewrite this:
MyObject *createObject() { return new MyObject(); }

or this:
MyObject createObject() { return MyObject(); }

If the second, then yes you are correct that returning a pointer will work (although a smart pointer is preferable to a raw pointer).

Quote:
 Thanks for the help rip-off, hope you understand my answers to your replies.

I hope I'm making sense with my replies. [grin]

##### Share on other sites
Quote:
 Original post by rip-offIs the function we are trying to rewrite this:MyObject *createObject() { return new MyObject(); }or this:MyObject createObject() { return MyObject(); }If the second, then yes you are correct that returning a pointer will work (although a smart pointer is preferable to a raw pointer).

I was actually talking about the first one, not only that, where are you using a pointer in the second version?

Quote:
 I hope I'm making sense with my replies. [grin]

You are, atleast... for the most part [grin]

##### Share on other sites
Quote:
Original post by J0Be
Quote:
 Original post by rip-offIs the function we are trying to rewrite this:MyObject *createObject() { return new MyObject(); }or this:MyObject createObject() { return MyObject(); }If the second, then yes you are correct that returning a pointer will work (although a smart pointer is preferable to a raw pointer).

I was actually talking about the first one, not only that, where are you using a pointer in the second version?

Well, if we are trying to re-write the second function, we could rewrite it to look pretty much like the first one, changing it to return an object allocated with new and to return a pointer. It doesn't currently use a pointer, you are right.

However, we are re-writing the first one (according to you). So, how does
Quote:
 2. Declare an object on the free store in the function, and have that function return a pointer to that memory to the calling function.

constitute a re-write, seeing as that is what the function currently does? [smile]

##### Share on other sites
Yep, now I am confused [SMILE]

I thought you said, that N° 2 was something we should avoid doing?

I thought that it would be possible since we would return a pointer on the heap.
Therefore, it would exist even if the function went out of scope, this pointer could then be deleted in the calling function right? It's my impression, this is what N° 2 stands for?

##### Share on other sites
Quote:
 Original post by J0BeYep, now I am confused [SMILE]

Me too. I reckon its a minor point however.

Quote:
 I thought you said, that N° 2 was something we should avoid doing?I thought that it would be possible since we would return a pointer on the heap.Therefore, it would exist even if the function went out of scope, this pointer could then be deleted in the calling function right? It's my impression, this is what N° 2 stands for?

Not to avoid completely, but to prefer returning a smart pointer rather than a raw pointer. A smart pointer such as std::auto_ptr will delete the object itself when the auto_ptr falls out of scope. However, str::auto_ptr has limitations so the more flexible boost::shared_ptr could be the best solution.

##### Share on other sites
Wow! References are really much easier to use/understand than pointers. I'd never use pointers if I could avoid them actually. Anyways good stuff, I'm sure though that there are better books in existence, this book is fine for now though.

I realized there's no quiz thread :o I'll just keep the answers in a notepad file on my computer.

1. What is a reference?
A simpler version of a compiler.

2. What is returned if you try and get the address of a reference?
The address of the variable it is referred.

3. Can references be reassigned?
Nope

4. Can you create a reference to a class?
No an object though

5. Is it possible to have null references?
No

6. What happens when a function prototype requests a reference.
The function is able to pass by references.

7. How does the client (the caller) of a function know that the function uses references? (where can the client look)
In the prototype.

8. What’s one method of allowing a function to “return” more than 1 value.
Passing by reference

9. What benefits are there for using const references as parameters to functions rather than allowing the compiler to make copies of the objects? When is this most useful?
It saves memory

10. According to the text, when is the best time to use references? When is the best time to use pointers?
Pointers should be used when it is necessary to reassign them, or make them null.

11. What is the primary thing to be careful of when returning references from a function?
Make sure the reference is declared outside of the function or it will cause a memory leak.

12. According to the author, is it a good idea to allocate memory within a function, if the primary purpose is to return the newly allocated object back to the caller? If not, what’s an alternate solution?
No. The memory should be allocated outside the function so it can be deleted properly.

[Edited by - Dbproguy on May 23, 2008 11:47:27 AM]