Object-Oriented Programming

CSCI-UA.0470-001

NYU, Undergraduate Division, Computer Science Course - Fall 2013

OOP Class Notes for 9/10/13

C++ Program Compilation and Linking

  • C++ implementation files are named .cc or .cpp
  • Header files
    • Specify other included headers
    • Contain declarations of classes, methods, functions, globals, and constants
    • Are named .h
  • Compilation process and static linking
    1. Implementation and header files are combined by and run through the preprocessor
    2. The resulting file is compiled into a .o unlinked file
    3. The .o may be linked with other precompiled libraries
    4. An executable binary, named a.out by default, results

C++ Style, Structure, and Syntax

  • C++ coders tend to be terse
    • Names are usually lowercase, separated by underscores
    • We will stick to Java style, considering that our class favors clarity
  • Code Organization
    • Classes are organized into namespaces
      namespace foo{
      
      }
    • Namespaces are delimited with ::. For example std::string references the string class from the standard library
    • The using keyword imports classes from a namespace
    • This differs from Java in that
      • Folder structure doesn't matter. In Java, the class org.example.Foo would be located in org/example/Foo.class
      • Namespaces use :: instead of .
  • Visiblity control differ from Java's
    • We can't specify that classes are public or private
    • We can make class member public or private, however.
    • The default access control is private
    • The specifiers are private: and public: and apply to all members following them until the next specifier
  • Immutability
    • When an argument should not be modified, the argument should be marked const
    • When a method should not modify its containing object, the method should be marked const
    • These annotations prevent the program from compiling if the function tries to change the referenced or owning object.
  • Arrays and their exact sizes can be specified in the class definition
  • Arrays of a constant size are inlined in the object, and are not objects in and of themselves, unlike arrays in Java.

Pointers!

  • Pointers!
    • Pointers are denoted with *
    • These behave just like C pointers
  • References - the & symbol
    • Don't confuse these with pointers!
    • In implementation, they are a pointer
    • But they do not allow NULL
    • They do not support pointer arithmetic
    • References allow passing objects java-style instead of by value
  • Calling a method on a value, reference, and pointer
    • T v.m() - for values
    • T& v.m() - for references
    • T* v->m() - for pointers
  • The this keyword gives a pointer to the containing object, not a reference, so be sure to use ->
  • Be careful about specifying object arguments! If you do not add an &, C+++ will pass the object by value (copy it) and objects can be very large!

Classes

  • Classes and their members are declared in the header
  • The implementation of the members goes in the .cc (or .cpp) and the name is declared with the prefix of the class name like Classname::methodName
  • As in Java, classes have a constructor that shares their name
  • If an instances is declared without being explicitly initialized, the no-argument constructor is automatically called, as C++ programmers love their brevity
  • If an instance of a class is initialized outside of the main program (as a constant variable such as the ORIGIN in our Point class), its constructor is called before the main method starts
  • Class declarations MUST end in a semicolon. Be careful.

The Preprocessor and Directives

  • The preprocessor, as its name implies, modifies the text of the program before it is compiled
  • Instructions to the preprocessor, or directives, begin each line with an # symbol.
  • Preprocessor directive lines do not end in semicolons
  • The #define directive is used to declare named constants
  • The #include directive includes the text of another file in the file that is being processed. This causes that file to be processed in turn
  • #include <foo> looks in the C++ standard header file path for foo
  • #include <foo.h> looks in the C standard header path for the C header
  • #include "foo" looks in the user's path
  • Circular #includes may lead to an infinite recursion; the compiler stops at some point and prints an error
  • To prevent these loops or conditionally exclude code, we have conditional directives
    • #ifndef NAME will include everything following it until #endif if no constant NAME has been defined
    • To include code only once, we may do
      #ifndef UNIQUE_NAME
      #define UNIQUE_NAME
      // Code here
      #endif
  • Compiler-specific directives are preceded by #pragma
    • One useful #pragma which makes sure a file is included only once without the trick above is #pragma once

Miscellaneous

  • C++ does not implement bounds checking for arrays. Hackers love this. Bounds checking should be implemented by the programmer, even for reads
  • Errors for bounds checking can be thrown with the throw keyword (see Point.cc)
  • To see the output of the preprocessor, run g++ -E source_file
  • C++ does not check that a value was actually returned, so int main() (the entry point) will happily compile even if you don't return a value. C++ will happily leave whatever happens to be in the register EAX as the return code.
  • if(variable = 1) will compile and will always be true, but you probably meant if (variable == 1), didn't you? To avoid these errors, put the constant on the left: if (1 == variable)
  • C++ supports operator overloading, so classes can define how symbols in the language work on them. One result of this are the << and >> stream operators, which are used in cin, cout and other stream objects like std::ostringstream (which is used in Point.cc as a string builder) to control input and output of a stream
  • Bjarne Stroustrup's answer to "Can C++ have this feature?" is apparently always "Yes!"