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