• Advertisement
Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Welcome to the GDNet C++ Workshop – Ch. 9

For a complete introduction to this workshop, please look here. As well, although this thread is temporarily mirrored in the "For Beginners" forum for easy access, the thread and workshop is actually located in a separate forum called "CPP Workshop" located Here. You can also find it on the main Forums page at the VERY bottom. Workshop Overview This workshop is designed to aid people in their journey to learn beginning C++. This workshop is targeted at highly motivated individuals who are interested in learning C++ or who have attempted to learn C++ in the past, but found that without sufficient support and mentoring they were unable to connect all the pieces of this highly complex but powerful programming language. This is a 'guided' self-teaching C++ workshop. Each student is responsible for taking the time to read the material and learn the information. The community and tutors that arise out of this workshop are here for making the learning process run more smoothly, but are not obligated to baby-sit a person's progress. Because everyone will be working from the same textbook (Teach Yourself C++ in 21 days 5th Ed.), students may find it easier to get answers to the specific questions they might have. There is no minimum age requirement, and there is no previous programming experience required. Additionally, this workshop does not attempt to defend C++ as a language, nor does it attempt to demonstrate that C++ is either more or less useful then other programming languages for any particular purpose. People who intend to start a discussion about the differences between C++ and ANY other languages (except as are relevant to a particular discussion), are encouraged to do so elsewhere. This workshop is for educational, not philosophical discussions. Tutors For an in-depth introduction to our tutors, along with the official list, as well as information on how to apply to be a tutor, look here. Over the duration of the roughly 21 weeks of the C++ Workshop there will be many questions asked and (hopefully) many questions answered. Unfortunately, not all answers are created equal. People tend to respond to questions for a number of reasons, not all of which are entirely self-less, and can sometimes even be dangerous to the learning process of those trying to absorb the information. Keep in mind that although your peers on the forum may be anxious and excited to help you, many of them may be learning the information for themselves, and not in a position to claim mastery of the subject. For this reason we’ve decided to establish a list of people we feel to be qualified tutors. People on our list are people we feel have attained a level of mastery such that their answers can generally be accepted as fact. Refer to the link above for the list of workshop tutors. Quizzes & Exercises Each week will have quizzes and exercises posted in the weekly threads. Please try and answer them by yourself. As well, please DO NOT post the answers to Quizzes and Exercises within this thread. Once it becomes acceptable to post the answers to quizzes and exercises, an additional thread will be created each week specifically for the purpose of posting quiz answers. If you try with reasonable effort but are unable to answer the questions or complete the exercises, feel free to post a clarification question here on the thread. Tutors, myself, or others will do the best we can to point you in the right direction for finding the answer.

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 this post


Link to post
Share on other sites
Advertisement
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.

Please post any questions you have on the chapter about References in this thread as usual.

Cheers!

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

PLEASE DO NOT POST THE ANSWERS TO THESE QUESTIONS OR EXERCISES. If you are unable to answer these questions, please ask for assistance, but DO NOT POST THE ANSWERS. Any question which is not marked with [Extra Credit] can be answered by reading your textbook. Questions which are marked [Extra Credit] either have been answered in the thread previously, or can be answered by doing a bit of research.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by rip-off
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).


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 this post


Link to post
Share on other sites
Quote:
Original post by J0Be
Quote:
Original post by rip-off
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).


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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by J0Be
Yep, 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 this post


Link to post
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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement