CS62 - Spring 2011 - Lecture 41

  • look at homework problem (templates)

  • Course evals

  • C++ for the day: default parameters
       In Java:

       void printInt(int num){
          printInt(num, 10);
       }

       void printInt(int num, int base){
          // ...
       }

       We could then call:

       printInt(15);
       15
       printInt(15, 16);
       f
       
       In C++:
       void printInt(int num, int base = 10){
          // ...
       }

       int base = 10 is called a "default parameter" and is equivalent to the two declarations above.

       printInt(15);
       15
       printInt(15, 16);
       f

       - A few things to note:
          - default parameters must come AFTER normal parameters to avoid ambiguity. The following is NOT ok:

          void printInt(int base = 10, int num) <--- BAD

          - You can have multiple default parameters. Parameters are filled in from left to right:

          void method(int v1 = 1, int v2 = 2){
             cout << v1 << ", " << v2 << endl;
          }

          method();
          1, 2
          method(15);
          15, 2
          method(15, 20);
          15, 20

          - default parameters are included in the declaration of the function, but not the definition


  • LAST C++ for the day: inheritance
       - what is inheritance?
          - inheritance is a way for classes to reuse and extend existing classes
       - why is it useful? what is it used for?
          - allows us reuse existing code
          - allows us to state shared behavior/ancestry between multiple classes
       - how does inheritance work in Java?
          - a class can inherit/build-upon another class by using extends
             public class A{
                ...
             }

             public class B extends A{

             }
          - when a class extends a parent class
             - it is of the type of the parent class and inherits all the member variables
             - it can access all of the public and protected instance variables
             - it inherits (i.e. has) all of the public and protected methods
             - it DOES NOT have access to any of the private information (but it still has them!)
          - What might be some examples?
             - parent: ball children: basketball, football, soccer ball
             - parent: bike children: mountain bike, road bike, beach cruiser
          - One of the uses of inheritance is to show shared ancestry/behavior. What if a class has multiple parents/ancestry?
             - Java does NOT allow for multiple inheritance
             - why not?
                - there can be ambiguity about which method to call if two parents implement the same methods
             - how does Java deal with this situation?
                - Java has interfaces
       - inheritance in C++
          - C++ shares many of the high-level inheritance characteristics of Java
             - classes can extend/inherit-from other classes
             - we've seen public and private scopes in C++, and C++ also has protected, defined similarly to public and private
             - when classes extend, they inherit public and protected methods and variables
             - inherited classes do NOT have access to any private information

             class A{
                ...
             }

             class B : public A{
       
             }

          - C++ uses, "IS-A" inheritance, that is B IS-A A. The public keyword specifies that it is public inheritance
             - private inheritance expresses a "HAS-A" relationship
          - look at inheritance.cpp code
             - IntCell class, which we've seen before
                - I've added a print method that prints out IntCell: <value>
             - MathCell is a class that inherits from IntCell
                - mathcell.h
                   - : public IntCell // inherits from IntCell
                   - added three methods
                   - overwrote print
                   - notice that there are no member variables defined here. We inherit that from IntCell (even though we can't access it)
                - mathcell.cpp
                   - similar to "super" in Java, we can call the constructor of the parent class by listing the name of the class, in this case "IntCell(initvalue)"
                      - if there is ambiguity and I want to call a parent method (i.e. if I've overwritten it), prepend it with ParentClass::, e.g. IntCell::print() would call the IntCell's print class
                   - we can call getValue() and setValue() from the parent class
                   - our own definition of print
             - mathcelltest.cpp
                - what will basicTest print out?
                   - 110
                   - we can call getValue on m, because it inherited that from IntCell
                - look at interestingTest
                   - Is "i = m" a legal assignment?
                      - yes, since MathCell is a subclass of IntCell, it's perfectly fine to call it an IntCell
                   - what will be printed out?
                      - if it were Java:
                         MathCell: 10
                         MathCell: 10
                      - but it will print out:
                         MathCell: 10
                         IntCell: 10
                - method dispatch
                   - Java uses what is called dynamic dispatching of method calls. At RUNTIME, the runtime system checks what type of object the method invocation is on and it calls that type's method
                   - By default, C++ uses what is called static dispatching of method calls. At COMPILE-TIME, the compiler looks at the type of the variable and the variable type dictates which method call is made
                   - why does C++ do this?
                      - efficiency! (of course)
                      - during run-time we don't have to check anything
                      - we also don't have to carry extra information around at run-time
             - virtual
                - we can tell C++ that we'd like a function to use dynamic dispatching with the virtual keyword
                - for any method that should use dynamic dispatching you need to prepend "virtual" before the function definition (in the .h file) of the PARENT/BASE class
                - for example, in our case, we would modify intcell.h to include:

                   virtual void print(ostream& out = cout);

                   instead of the original version
                - now if we run interestingTest we will use dynamic dispatching and we will get the same answer as in Java
                   MathCell: 10
                   MathCell: 10