CS62 - Spring 2011 - Lecture 32

  • Admin
       - Professor Kauchak's office hour changes this week
          - today: moved to 4-5:30
          - Thursday: 1-3
       - Assignment 10
          - use the documentation
          - private methods
          - key vs. priority

  • Installing C++
       - Mac
          - download Aquamacs (http://aquamacs.org/) for file editing
          - install xcode (this should be included with your original install disk or you can download from Apple, but there may be a small fee)
       - Windows
          - download Emacs (http://www.gnu.org/software/emacs/windows/faq.html)
          - For the compiler, there are two options:
             - http://www.cygwin.com/ which is a command-line utility. When you install, make sure to include the C/C++ packages.
             - http://www.mingw.org/ which has a basic command-line and the compiler

  • Question: What happens in Java when you have two things in the namespace called the same thing?
       - There is ambiguity and so the compiler forces you to use the full package names, e.g.
          java.util.ArrayList

  • Compiling multiple files: look at bankaccount.cpp code
       - bankaccount.h
          - header file with a few more declarations
          - none of the examples here have private methods, but you can also declare those in the header file
       - bankaccount.cpp
          - method definitions
          - again, notice that the private variables only occur in the header file
       - bankaccounttest.cpp
          - notice we put the main method in another class
          - straightforward use of the class
          - notice again the calls to the constructor
       - compiling
          - we now have multiple class files that we want to compile
          - can't just do it with one line
          - C++ has three main steps in compiling
             - preprocessor
             - compile to machine code
             - link all of the machine code files into one project
          - preprocessing happens automatically when compiling
          - need to compile each .cpp file individually
             g++ -c bankaccount.cpp
             g++ -c bankaccountest.cpp
             
             - the lines above could be done in either order, why?
             
             g++ -o bank bankaccount.o bankaccountest.o
             
             - link all of the files together and make a binary
                - binary is called bank
                - you can get "link" errors if, for example, you haven't defined a method that you said you would
             - why don't we have to compile the header files?
                - they get #included and implicitly compiled. You can get compiler errors in header files


  • pointers (reference in C++)
       - in Java, we have two high-level types of variables
          - built-in types
          - references to objects
          - (and really arrays as a third type)
       - what do you think a reference actually is, i.e. how is represented in memory?
          - a reference is just a memory address
          - traditionally, a memory address was represented as 32 bits
             - so an object variable uses up 32 bits
             - how much memory can you address with 32 bits?
                - 2^32 different numbers = ~4 billion numbers
                - each number represents a byte
                - 4 gigabytes
          - my mac has 4 GB of ram, do you think this is a coincidence?
             - again, traditionally, memory was accessible by 32 bits
                - traditionally, most processors operated in 32 bits
             - what is a 64 bit processor?
                - it's a processor that operates memory addresses on 64 bits
             - what is the advantage?
                - much bigger memory space
             - disadvantages?
                - if we only need 1G of memory, we're going to waste space because references now take up twice as much space
             - you will hear people talk about 32 JVM vs. 64 bit JVM
                - since java is a "virtual machine" it can have either 32 bit or 64 bit addresses
       - in C++, we have three variable types. We've seen two. What are they?
          - built-in types
          - object variables on the stack
          - (and again, we also have arrays)
       - the third general type are "pointers" or "pointer variables" (similar to references)
          - Like Java references
             - a pointer is a variable that stores a memory address
             - a pointer can only point at an object of that type (more or less)
          - Unlike Java references
             - not all object variables are pointer variables (as we saw last time)
                vector<int> v; // is not a pointer/reference
             - to distinguish, we put a '*' after the type indicates that variable is a pointer variable rather than a traditional variable
             - unlike Java, we can have pointers to built-in types as well as objects
          - A few examples:
             vector<int>* vPtr;
             string* sPtr;
             int* intPtr;
             IntCell* cellPtr;
       - Using pointers
          - Like Java, we can use the "new" command to create a new object
             - where do you think this is stored? On the heap!

             vector<int>* vPtr = new vector<int>; //

             the "new" command returns the address of the newly created object

             - notice that:
                vector<int> v = new vector<int>; // will NOT work
             - why?
                - different types
                   - the new command will return a vector<int> pointer
                   - you're trying to assign it to a vector<int> variable

                   "conversion from Ôstd::vector<int, std::allocator<int> >*Õ to non-scalar type Ôstd::vector<int, std::allocator<int> >Õ requested"
          - A pointer is just a memory address (the type is for type checking by the compiler)
          - Because it is just a memory address, you use them slightly differently than a normal variable. To access the data that the variable "points" to, you need to "dereference" the pointer.
          - "dereferencing a pointer": Given a pointer: vector<int>* vPtr;
             - you can dereference the pointer again using the '*' operator and then use methods using '.':
                (*vPtr).push_back();
                (*vPtr).size();
             - you can use the '->' operator (which is generally preferred):
                vPtr->push_back();
                vPtr->size()
             - look at pointers.cpp code
                - what does objectPointer do?
                   - creates a new int vector
                      - where is it created? on the heap
                      - for the default constructor, you can either include or not include the parenthesis
                   - adds the numbers 0 through 9 into the vector (note the use of (*v) to dereference the pointer
                   - prints out the numbers
                - what will be printed out?
                   - remember, a pointer is just an address. The cout statements printing v, will just print the memory address where the object is stored
                   - will this change during the method call?
                      - no, we never assign anything different to it so it won't change
                   - all the address print statements will print the same address
                - what does objectPointersBetterApproach do?
                   - same thing, however, we're using the "->" operator rather than dereferencing the pointer
                   - in general, a better approach
          - There are two ways to get a memory address (i.e. the value for a pointer)
             - using "new", that is an address on the heap (like we've seen)
             - you can get the address of any variable using the '&', "address-of" operator
                vector<int> v;
                vector<int>* vPtr = &v;

                int x = 10;
                int* xPtr = &x;
          - look at pointers.cpp code
             - what will be printed out by the objectPointers2 method?
                - 10, 20
                - vPtr is just a pointer to vec, so the push_back calls push values onto vec
                - where is vec stored?
                   - on the call-stack! (remember this...)
                      - if you play with these programs you'll actually notice a difference
                      - when we printed out the address above on the heap it was something like:
                         0x100100080
                      - here, when we print out the address on the stack it's at:
                         0x7fff5fbff8f0
                      - which are not very close to each other!
             - what will be printed out by the address method?
                - the address of x, again on the call-stack
                - 10, which is just the value of x
                - notice that even though x is a built-in type, we can point to it
                   - when we dereference a built-in pointer, we just get the value (just like for object pointers we got the object)
                - in general, most of the time, you don't use pointers to built-in types, just objects
             - what will be printed out by the changingValue method?
                - The address doesn't change
                - print out 11