Chapter 13 – Introduction to Classes Objects are created from ADT’s ( abstract data types ) that encapsulate data and functions together. In OOP ( object-oriented programming ), a programmer can use existing ADT's ( classes that are considered part of the language ) or create their own new ADT's ( programmer defined classes ). In the C language, structures may be created, but they cannot include definitions of functions. C does NOT support object-oriented programming. In C++, structures may be created that declare data and functions using the keywords struct or class. The preferred term in C++ is class. Conceptual view of a class – data and functions are encapsulated. Member Data double width double length double area Member Functions void SetData (double w, double l ) void CalcArea ( ) double GetLength ( ) double GetArea ( ) member data is generically referred to as: member function are generically referred to as: attributes behaviors The state of an obect is the values of it's member variables at a particular instant in time. Definition of a class – the class is the primary construct used to create objects in C++ class Rectangle { private: double width, length; // private and public are access specifiers public: // member function PROTOTYPES void setWidth (double w); void setLength (double l); double getArea ( ) const; double getLength ( ) const; double getWidth ( ) const; // sets the member data variable width to w // sets the member data variable length to l // uses Length and Width member data to calculate Area // and returns it as a doubleing point value. // returns the value of the Length variable // returns the value of the Width variable }; The keyword const in the function prototype specifies that the function will not change any data stored in the calling object. If const is used in the function prototype it must also be used in the function header. Access specifiers are used to define the private data and function members and the "public interface" to a class (the public member functions) Data or functions declared under access specifier private are inaccessible to functions outside of the class. Data or functions declared under access specifier public are directly accessible by any function outside of the object. Normally the rule is: private data, public functions. 1 For a class, the default access specifier is private. Class member functions are defined similarly to regular functions. Typically the declaration of the class includes the member data definitions and the member function declarations (prototypes). The definitions of the member functions are usually outside of the class declaration ( the class declaration has member function prototypes ). Defining the member functions outside of the class requires the use of a binary scope resolution operator ( :: ). class function void Rectangle :: setWidth ( double w ) // define the function setWidth which is a member function { // of the class Rectangle width = w; } If a function is defined in the class declaration the function is said to be “inline” Defining an instance of a class. An object is an instance of a class. Defining a class object is referred to as instantiating the class. Given the declaration of class Rectangle above, the following defines an object of type Rectangle. Rectangle box; To set the values of the member data for object Box, member functions must be used because the member data was declared private. box.setWidth ( 3.0 ); box.setLength ( 5.0 ); double area = box.getArea( ); // sets Box’s width to 3.0 // sets length to 5.0 // gets box’s Area The syntax of the above function calls is: object . This is similar to accessing members in a structure. member_function (argument-list); Member function naming conventions By convention, if a member function returns a value, its name often begins with get. If the member function accepts parameters and uses them to set the value of member data, the function name often begins with set. getWidth( ) setWidth( 5 ) // a member function name suggesting it would return a value // a member function name suggesting it would accept a parameter and change the // value of a member variable Private member data and functions Objects often have some variables and functions that are meant only to be used internally. They are not intended for use outside the object. These data and function members are declared to be private. A private member function can only be called from a public function that is a member of the same object. Usually class declarations are stored intheir own header files (.h). Member function definitions are stored in their own source files (.cpp). Conditional compilation preprocessor directives ( aka preprocessor wrappers ) These are used in a .h file #ifndef RECTANGLE_H #define RECTANGLE_H … // class declaration #endif 2 The purpose of these is to prevent a class declaration from being included more that once. Constructors A constructor is a member function that is automatically called when a class object is created. Constructors are not required but usually are included in the definition of a class. Constructors are useful for initializing member data in an object when the object is created. A Constructor: is called automatically (if it exists – they are NOT required) when the object is created has the same name as the class must be public cannot have a return type ( not even void…) cannot be explicitly called can be thought of as an initialization routine for a class The general format of a constructor: <class_name> :: <class_name> (parameter_list) { < constructor body> } For a class named Account, a constructor definition in a source file (.cpp) would look like this: Account::Account( ) { <constructor body> }; Default Constructor When a constructor does not have to accept arguments, it is called an object's default constructor. A default constructor does NOT require the parentheses ( ) that are required for a constructor that DOES require at least 1 parameter. If Rectangle is the name of a class and Rectangle has a default constructor, the following statement would create several Rectangle objects. Rectangle r1, r2, r3, r4; // create several objects ( instances of the class Rectangle ). // these objects are created using a default constructor. Destructor A destructor is a member function that is automatically called when an object is destroyed. A destructor has the same name as the class preceded by a tilde ( ~) Demo::~Demo(void) If a constructor was used to dynamically allocate memory for an object, a destructor may be used to release the dynamically allocated memory. Like constructors, destructors have no return type Destructors cannot accept arguments, so they never have a parameter list Destructors are not usually needed unless files are being processed or memory was dynamically allocated. 3 Constructors that accept arguments Often information must be passed to a constructor in order for the object to be properly initialized. Since the constructor is automatically called when the object is created, the argument is passed to it as part of the object declaration. If Account is the name of a class with a constructor that requires a value of type double for the initial account balance, the following statement would create an Account object with an initial balance of $75.43. // create an object named myAccount and supply the required constructor argument. Account myAccount( 75.43 ); // initial balance is 75.43 Constructors may also have default arguments. Default arguments are passed to parameters automatically if no argument is provided in the function call. If class account has a constructor with a default argument for an account balance of $50, the following statement would create an Account object with the initial balance provided by means of a default argument in the constructor. // create an object named newAccount and initialize the initial balance to $50 ( default argument value ). Account newAccount; // initial balance is 50.00 Overloaded Constructors More than one constructor may be defined for a class. Any time functions are overloaded, the functions must have different parameter lists. for class InvItem, the following constructors are declared ( prototypes ): InvItem( char * desc, int units ); InvItem( char * desc ); InvItem( int units ): The following would be valid object declarations for objects of the class InvItem: InvItem item1( "wrench", 20 ); // description and units provided InvItem item2( "hammer" ); // description only InvItem item3( 10 ); // units only A class may have only one default constructor and only one destructor You may declare and work with an array of objects and also with a pointer to an object When an array of objects is created, the constructor is called for every element in the array. This can be done using an initializer list. InvItem inventory[3] = { 35, 55, 80 }; If the constructor requires more than one argument, the initializer must take the form of a function call using the constructor name as the function name. The example below is based on the class InvItem described above which has 3 constructors: 1. a constructor that takes a pointer to a character string as a single argument 2. a constructor that takes a pointer to a character string and an integer 3. a constructor that takes an integer as a single argument (1) (2) (3) InvItem Inventory[3] = { “Adjustable Wrench”, InvItem(“Screwdriver”, 20), 35 }; Accessing members of objects in an array cout << setw(14) << inventory[ i ].getDescription( ); prints using a pointer to a character string 4 Accessing members of an object using a pointer Rectangle* rPtr; //declare rPtr to be a pointer to a Rectangle object. rPtr = &r1; //assign rPtr the address of Rectangle object r1. cout << “The width of the rectangle is “ << (*rPtr).getWidth() << endl; You must dereference the pointer before you try to access the member function (because the member access operator has higher precedence that the indirection operator). You may also use the arrow operator ( -> ) to dereference a pointer to an object and then access a member in the object. rPtr -> getWidth() means the same thing as (*rPtr).getWidth(); 5