Sixth lecture; classes, objects, reference operator. 1
Some notes on the administration of the class: From here on out, homework assignments should be a bit shorter, and labs a bit longer. My office hours are 2-4pm Tuesdays and Thursdays, my office in 228 Hardymon feel free to stop by. The virtual desktop now has Tortoise installed by default, so you won t have to go through that step using it. But for the labs, you should be able to just use the tools (Visual Studio and Tortoise) installed on the lab machines themselves getting started with the virtual desktops was to make sure everyone was familiar with them and to give everyone base line functionality through them. You can continue using them if you want, but don t need to. 2
An email I received from a student this morning. I promise source control is useful. It s great. It s really helpful. It just has a bit of a learning curve, and hopefully we re past that but the bigger these projects get, the more useful it gets. It s a great habit to be in to write all of your code under source control and use it for frequent backups. 3
Dr. Jaromczyk asked me to relay information about the ACM programming competition; in 2010, the UK team went to the world finals in China. The local round is starting up this Thursday afternoon. http://www.cs.uky.edu/~jurek/ukspc/2012/index.sphp 4
Yeah, this is going to be the second (er, fifth?) slide in a lot of lectures. 5
Not the last time you ll se this. Why? Because it s important. 6
Parts of a function definition. 7
Debugger commands. Again, it will help you a lot to be familiar with these. 8
Going in to some of the stuff we discussed the mechanics of in the last class in more detail, to make sure we cover the concepts thoroughly. What is a variable? 9
So, we declare a variable. What does it do? This statement gives us a variable named a that we can access later (by the scope rules we ve discussed before). It assigns the value of 5 to it. It also allocates a memory location for a to store any value we assign to it. 10
The important concepts for passing variables to functions: Pass by value, pass by reference. It is very important to understand the difference between the two. 11
When we pass by value, C++ creates a new variable (and allocates new memory for it) within the function. 12
When we pass by reference, the same variable gets reused. This happens because the function, instead of just getting the value of the variable, gets passed its memory location, and can then access the memory that contains the original variable. 13
Syntax for passing by value type, variable name. Simple. C/C++ actually has pretty simple rules for pass by value/reference; if you see the reference declarator (&), it passes the value by reference, otherwise it passes by value. 14
Here we have the reference declarator (&); this passes the value by reference, so not only do we reuse the memory location, but this function can now modify the value stored in the variable. 15
And so it is often the case when we re passing by reference that we don t want the function to be able to do this, so we can use the const keyword here to prevent the function from changing the value of the variable. 16
We already talked about the reference declarator -- &. The ampersand character is also used as the reference operator. As we ve already discussed, C++ (and more so C, as this behavior comes directly from C) is a fairly old language, and derives from the days where character sets were more limited, and so they needed to reuse symbols in the language. So & can be used both as a declarator in a function parameter, but as an unary operator in a normal expression as well. When we use this in a normal expression, it returns the memory location of the attached variable. While we ll use it today to demonstrate that pass-by-reference semantics reuse memory locations and pass-by-value don t, this operator will become a lot more important when we talk about pointers soon But first 17
We ll talk a bit about classes and objects. We ve kinda skirted around this so far; we ve talked about strings and vectors (which are classes), but not a whole lot about how they differ from scalar types. A class is an abstract type; like string, vector, etc. In the same way as int, double, etc are types, string and vector are classes. An object is an instantiation of a class. When you declare a variable of a class such as string s; you get an object of that class. s is the object, string is the class. Classes have a lot of differences from the scalar types; one of the most notable is that while scalars do not have any default initialization, classes do string s; defaults to an empty string. Even without assignment, classes have default values. 18
This doesn t mean they can t be initialized however, as seen above. This slide also shows us calling a function length(), above within the class. We call these functions methods or member functions, and we ve used them a bit before, but now we ll talk about them more explicitly. 19
Another operator! This, the humble period, is the member operator (also called the structure reference operator). It s what we use to access the members within an object. Like the other operators, it takes part in expression evaluation (remember: everything is an expression), by finding the method within the object it s used on to call. We ve seen: string s = Hello, world! ; cout << s has << s.length() << characters. << endl; The period in s.length() is an example of the operator it lets us call the length method inside the object s. 20
Now some of the methods of the string class. We ve talked about declaring and initializing strings (and reading them in from the console, too), but now let s talk about some of the methods we can call on string objects. 21
size()/length() these are the same method, and both return the number of characters in the string. resize() resizes the string. The first argument is what size the string is being resized to, the second argument is the value to replace any added characters with. By default, it will use spaces. s.resize(3); // resizes the string to 3 characters; any additional characters are lost, if it adds characters, it will add spaces s.resize(10, * ); // resize the string to ten characters; if this causes characters to be added to the string, it will add asterisks. []/at() [] is the index operator. You put an integer value in it, and you get back the character at that index NOTE: strings are zero-indexed, which means the index of the first character is 0. at() is the same operation as a function. Causes an error if you ask for an index that doesn t exist in the string. char c1 = s[2]; // c is the third character in the string char c2 = s.at(2); // does the same thing as the above clear() resets the string to an empty string find() finds a character or string within the string, will return string::npos if it is not found; string::npos is equal to -1. 22
string s = Hello, world! ; if( s.find( * ) == -1 ) { cout << No asterisks. << endl; } int iindex = s.find( e ); // this will return 1, as e occurs at position 1 remember that strings start at position 0! + - we can add strings. This works pretty much how you d expect. Note: you can t add a literal string to another literal string, but you can add a literal string to a string object. string s = world ; string s2 = Hello, + s; // s2 is now Hello, world string s3 = Hello, + world ; // compiler error; you cannot add a literal string to a literal string 22
The other class we ve talked about vector. Vectors are a parameterized type; to declare one, we have to give it another type as a parameter: vector<int> will give us a vector of ints, vector<string> gives us a vector of strings. 23
Some methods in vector: size() returns the number of elements in the vector resize() resizes the vector to the given size. The optional second parameter tells it what default value to use if it has to add elements. vector<int> v; v.resize(10, 44); // Now v is a vector of ten ints, all with value 44. [] / at() works much like in string, which shouldn t be too surprising, as a string is, basically, a vector of characters with a few features added. int a = v[5]; // takes the sixth element in v remember vectors are zero indexed too int b = v.at(5); // does the same as above push_back() adds the parameter to the end of the vector pop_back() removes the element on the end of the vector v.resize(0); // v now has no elements v.push_back(3); v.push_back(4); // v now has two elements: 3 at position 0, 4 at position 1. v.pop_back(); // v now has one element: 3 at position 0. 24
We ve talked a lot about implicit casts, especially how they work with bool values, as that matters a lot for conditional statements. We re going to talk briefly about explicit casts, now when you specifically want an expression to be a different value than what it is by default 25
This is the general syntax for it when we re talking about scalar values we ll talk about casting objects later, but for scalars, this is how to do it. And, like vectors, this is parameterized the type you put in the angled braces is the type C++ will try to give you. The expression can be anything, well, because everything is an expression Example: string s = ABC ; cout << s.at(0) << endl; // This will write A to the console; the return type of string::at() is char, and cout writes chars to the console as letters int a = s.at(0); // A now holds the value 65; a char (the normal type of string::at()) can be implicitly converted to an int cout << a << endl; // This will write 65 to the console, as a is an int, and ints get written to the console as decimal numbers cout << static_cast<char>(a) << endl; // This will write A to the console, as chars get written out as letter, and the static_cast convers a to a char 26