[Skip Navigation] [CSUSB] / [CNS] / [CSE] / [R J Botting] / [CSci202] / objects
[Text Version] [Syllabus] [Schedule] [Glossary] [Resources] [Grading] [Contact] [Question] [Search ]
Notes: [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]
Labs: [01] [02] [03] [04] [05] [06] [07] [08] [09] [10]
Fri Mar 18 14:50:42 PDT 2011

Contents


    Rough Notes on Objects and Clases

      These notes come in two parts: [ C++ Classes ] and [ Organizing and compiling your code ]

      C++ Classes

        Class in the Unified Modeling Language -- UML

        You should get into the habit of sketching your class before you code them. In the UML you show the name first followed by the data or attributes, and finish with a carptment full of functions or operations. Here is an example

        [Class Counter haqs a single int value that can be incremented and decremented]

        class Counter


          public:
        1. initialize value
        2. increment value
        3. decrement value
        4. get value

          private:


          1. int value


        Coding classes

        In this book classes are described like this:
        1. Application -- A test or driver program (a .cpp file with a main() function [ testCounter.cpp ]
        2. Definition -- A C header .h file [ Counter.h ]
        3. Implementation -- A collections of functions in .cpp files [ Counter.cpp ]

        This is excellent software Engineering: you should develop all three things for any class.

        It is also a pain to set up for a small project.

        And it takes a makefile on UNIX to work simply..... more later. In the example above we would need these two recipes in our Makefile

         testCounter: Counter.o testCounter.cpp Counter.h
         	g++ -o testCounter Counter.o testCounter.cpp
         Counter.o: Counter.h Counter.cpp
         	g++ -c Counter.cpp

        Developing these files is easy if you have a set of skeleton files available. I have stored a set of files on the WWW which are ready to be used whenever you need a main program use [ main.cpp ] For a class definition use [ class.h ] To define the implementation of a class use [ class.cpp ] For each function copy these blank file for each [ function.cpp ] or [ void_function.cpp ] and edit them.

        Please use them!

        Defining a Class

          A class is the C++ way of creating a complete new data abstraction with a hidden implementation and a usable set of values and operations.

          Notice keywords: class, public, private.

          Notice the #ifndef & #define - and why its needed!

          Notice the semicolon at the end of the class definition and the function prototypes.

        . . . . . . . . . ( end of section Defining a Class) <<Contents | End>>

        Implementing a Class

        Notice that implementation #include the header file.

        Notice the double_colon in the function implementations.

        Notice the absent semicolon at the end of the function implementations.

        Notice: lots of small functions. Highly modular.

        Constructors

        Describe how to create a new object - initial values and things like that. Use them!

        Syntax and Semantics -- VITAL

        Read, use, practice, remember those in the book! Here are my personal notes on the syntax and semantics of classes.

      1. prototype::=The header of a function describing how it is called and what it returns without describing how it does it.

      2. prototype::syntax= returned_type function_name( formal_argument_types) semicolon.
      3. function_implementation::syntax=returned_type function_name( formal_argument_types) compound_statement.

      4. class_member_function_definition::= function_implementation,

      5. formal_argument_types::= list_of_type_names.

      6. function_call::syntax=function_name(actual_arguments).
      7. actual_arguments::syntax=expressions_of_a_matching_type.

      8. semicolon::= ";".
      9. class::=a struct with operations and functions.
      10. class_declaration::syntax= class class_name { class_declarations } semicolon.

      11. class_declarations::= public: public_declarations private: private_declarations... .
      12. private_declarations::= many declarations.
      13. public_declarations::= many declarations.

      14. declaration::= variable_declaration | function_prototype; | ... .

      15. member_function_declaration::syntax=returned_type class_name double_colon function_name ( formal_arguments ) compound_statement.

      16. double_colon::=colon colon.
      17. colon::= ":".
      18. object::=an instance of a class.

        For more: [ Object in objects.glossary ]

        Struct vs class

        A struct assumes things will be public but a class assumes that things will be private.

        Example: Suppose a program declares:

         	struct S { int i; };
         	S s;
         	class  C { int i; };
         	C c;
        Then s.i will compile but c.i will not.


        (struct_style): Use struct for objects that have a structure but no defined operations/functions.

        How to use Objects

        You can't use a class as an operand! You can use objects (in a class) as operands. There are three simple ways to do this:
        1. IN(slow): Objects that get copied: Class_name argument
        2. IN(fast): A reference to the object is used, BUT you can not change the object: const Class_name & argument_name
        3. INOUT: A reference to the object is used: Class_name & argument_name

        Example of a complete program using classes

        This program [ life.cpp ] is still a little old fashioned (class names should be capitlized for a state).

        To help you figure it out look at [ life.png ] (the UML diagram of the classes).

        UML Please

        Please include a rough diagram of the classes in your code. Scribble them in a blank spaces in the code. Or on the reverse side of the printout.

        Use the Unified Modelling language. For example if you define a class Person with name, address, and age plus function born(string,string), die(), get_age() then draw a diagram like this

        [Class Person in UML]

        If you declare a class Counter to handle counting....

        [Counter with int state, a constructor, and two functions]

        A very rough UML sketch is an easy and fast way to start thinking about any new class you are about to code. Engineers have a tradition of using napkins for this kind of design.

        Remember that when you are stuck writing or debugging code, it helps to shift to pictures and diagrams. Rough UML can help.

        Exercise

        Does the above diagram show the same class as the first UML diagram in this set of notes?

        There must be a Main Program to test classes

        When asked to develop one or more classes you should also develop and hand in a main program that tests the classes. A test of a class is called a "Unit Test". The main program is a good place for a rough picture of all classes tested and all tested connections between them.

        I find that wrting the tests first helps me understnad the classes I have to write better. I use

         	#include <cassert>
        so that the main program can test that an operation/method/function works
         		assert( object.operation(data) == expected_result);

        I'll try to demo this in a lecture/discussion.

        Common Syntax errors in C++ classes

        • Forgetting the ';' after the last '}'.
        • Trying to initialize an attribute in its declaration. Do it in constructors.
        • Forgetting Scope rules.

        Common Semantic errors in C++ classes

        • Not modeling the real world.
        • Putting data about Y inside class called X. Putting operation in the wrong class.
        • Trying to use a private member outside its class.
        • Putting something in a class that belongs in the main program.
        • Not enough constructors...

        Good style in C++ Classes

        • Class names start with a CAPITAL LETTER.
        • Attribute and function names start with a lower case letter.
        • Attributes are nearly always private and function/operation public.
        • Aim for many tiny operations rather than a few big ones.
        • Don't put all the intelligence and control inside one object.

        Old Examples of Classes Online

        [ money0.cc ] [ w3.cc ] [ w4.cc ] [ life.cc ] [ life1.cc ] [ nim.cc ] [ nimturn.cc ] [ fixarray.cc ]

      . . . . . . . . . ( end of section C++ Classes) <<Contents | End>>

      Organizing and compiling your code

        Introduction: Choices

        You can choose a very simple technique that gives long compilations but is well suited to small problems. You can choose more complex techniques that are suitable for real problems with tens of thousands of lines of code and a life time of a decade or two.

        Key point: A reusable piece of code has two parts: a definition and an implementation. The definition tells the compiler what a client is permitted to do with the reused code. The implementation tells the computer how to meet the permitted requests. Notice that it is not necessary for the compiler to use the implementation information to figure out how to to compile client code.

        Simple but Slow

        Put the definition and the implementation on the same file: foo.cpp say. Tell the compiler to read(include) foo.cpp as it reads and compiles the client program:

        foo.cpp


        1. Definition
        2. Implementation

        client.cpp


        1. ...
        2. #include "foo.cpp"
        3. ...
        4. Use foo

        Compile the whole thing by this command:
        	Q client.cpp

        Note. You can set up 'vi' to do this when you are in command mode and tap 'q'. Simple....

        This is what the compiler actually compiles:


        1. ...
        2. Definition
        3. Implementation
        4. ...
        5. Use foo

        The #include is replaced by the contents of the included file.

        Problems: must recompile the whole of foo.cpp every time you compile the client. If you share foo.cpp with other people they must be able to read the whole of it and may rely on you never changing the implementation. Finally you work with a large foo.cpp file.

        Separate Definition from Implementation

        Place the definitions in a file called foo.h and the implementation in foo.cpp. Note, that the implementation must know what the definitions are and so it must include foo.h. The client tells the compiler to include foo.cpp and foo.cpp includes foo.h:

        foo.h


        1. Definition

        foo.cpp


        1. #include "foo.h"
        2. Implementation

        client.cpp


        1. ...
        2. #include "foo.cpp"
        3. ...
        4. Use foo

        Compile the whole program by this command:
        	Q client.cpp

        You can now work on the implementation file without touching the definition file. This may save time editing. It also encourages you to freeze the definition. The programmers who write client code will be thankful!

        Problem... we still compile the whole of the implementation every time we compile the the client.

        Precompile the details

        foo.h
        1. Definition

        foo.cpp


        1. #include "foo.h"
        2. Implementation

        Compile foo.cpp only when it is or foo.h is changed
        	g++ -c foo.cpp
        This generates an "objectcode file": foo.o That can be reused without being recompiled. You can give people copies of foo.h and foo.o and they will not be able to read (and steal?) your foo.cpp code.

        client.cpp


        1. ...
        2. #include "foo.h" // not foo.cpp
        3. ...
        4. Use foo

        Compile the program in two stages. Only if you change foo.cpp or if foo.cpp has never been compiled.

        Compile client.cpp and link in foo.o by this command:

        	g++ -o client client.cpp foo.o -lm ...

        This works because compiling the parts of the solution is a separate task to linking them together.

        Complex projects

        When you have many pieces of code and many clients it helps to spend time documenting the rules and letting your systems "make" program decide the optimum set of steps to recreate an uptodate program. On UNIX you create a "makefile".

        For example I have a complex program abc.cpp that uses three pieces of code a,b and c. Another program in the same project is called ab.cpp and only uses a and b. Each reused piece of code is split into a header defining the code and an implementation file:

        a.h


        1. Define a

        a.cpp
        1. #include "a.h"
        2. Implement a

        Similarly for b and c.

        abc.cpp


        1. #include "a.h"
        2. #include "b.h"
        3. #include "c.h"
        4. Use a, b and c

        ab.cpp
        1. #include "a.h"
        2. #include "b.h"
        3. Use a and b only

        Thus we want to precompile a,b, and c giving a.o, b.o, and c.o precisely when the relevant files are changed. We don't need to recompile b or c if only a has changed. We do not need to compile abc, a,b, or c when ab changes. and so on.

        These facts can be recorded in a special file for the project called `makefile'. This lists each thing plus a list of the things it depends on. Then it gives a set of instructions for making the target file out of its dependents. The commands must by preceded by a TAB character, or the 'make' program will not work.


        (makefile):


           abc: abc.cpp a.o b.o c.o a.h b.h c.h
           	g++ -o abc abc.cpp a.o b.o c.o -lm
           ab: ab.cpp a.o b.o a.h b.h
           	g++ -o ab ab.cpp a.o b.o c.o -lm
           a.o: a.cpp a.h
           	g++ -c a.cpp
           b.o: b.cpp b.b
           	g++ -c b.cpp
           c.o: c.cpp c.h
           	g++ -c c.cpp

        Compiling a program is now very easy. To compile abc.cpp:
         	make abc
        Or since 'abc' is the first thing in the makefile we can just type:
         	make
        To compile ab.cpp do this:
         	make ab
        etc. Similarly whenever you change any file, you just input a make command and the make program will do the minimum work needed to reconstruct the new programs.

        Q also understands Makefiles and make and will use them if you have them:

         	Q abc.cpp
        will call make abc for you.

        For more information on make, look in [ make.html ] my notes on Makefiles.

        File Structures in a Project with classes

        As a rule, a class called Name should be declared in
         		Name.h
        and its functions should be in
         		Name.cpp
        and it should have a main program that tests it in
         		test.Name.cpp

        Working Faster

        Make some blank .h and .cpp files for a Blank class and Operations.

      . . . . . . . . . ( end of section Rough Notes on Objects and Clases) <<Contents | End>>

      Glossary

    1. accessor::=`A Function that accesses information in an object with out changing the object in any visible way". In C++ this is called a "const function". In the UML it is called a query.
    2. Algorithm::=A precise description of a series of steps to attain a goal, [ Algorithm ] (Wikipedia).
    3. class::="A description of a set of similar objects that have similar data plus the functions needed to manipulate the data".
    4. constructor::="A Function in a class that creates new objects in the class".
    5. Data_Structure::=A small data base.
    6. destructor::=`A Function that is called when an object is destroyed".
    7. Function::programming=A selfcontained and named piece of program that knows how to do something.
    8. Gnu::="Gnu's Not Unix", a long running open source project that supplies a very popular and free C++ compiler.
    9. mutator::="A Function that changes an object".
    10. object::="A little bit of knowledge -- some data and some know how". An object is instance of a class.
    11. objects::=plural of object.
    12. OOP::="Object-Oriented Programming", Current paradigm for programming.
    13. Semantics::=Rules determining the meaning of correct statements in a language.
    14. SP::="Structured Programming", a previous paradigm for programming.
    15. STL::="The standard C++ library of classes and functions" -- also called the "Standard Template Library" because many of the classes and functions will work with any kind of data.
    16. Syntax::=The rules determining the correctness and structure of statements in a language, grammar.
    17. Q::software="A program I wrote to make software easier to develop",
    18. TBA::="To Be Announced", something I should do.
    19. TBD::="To Be Done", something you have to do.
    20. UML::="Unified Modeling Language".
    21. void::C++Keyword="Indicates a function that has no return".

    End