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

Started by
17 comments, last by Dbproguy 15 years, 11 months ago
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.

Advertisement
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.
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.
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]
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]

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]
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?
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.
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]
--Dbproguy - My Blog - Tips, Opinions and Reviews about C++, Video Games, and Life

This topic is closed to new replies.

Advertisement