EEL 3801 Part VI Fundamentals of C and C++ Programming Classes and Objects Object-Oriented Programming We think in terms of objects. Objects can be: –animate –inanimate Objects have: –attributes (i.e., color, size, weight, etc.) –behaviors (i.e., move, rotate, cry, laugh) –communication with other objects EEL 3801 – Lotzi Bölöni C vs C++ C is a procedural language –it revolves around functions –functions create motion or action –data exists mainly in support of actions C++ is an object-oriented language –it revolves around classes of objects –a class is based upon the C structure EEL 3801 – Lotzi Bölöni Classes Similar to structures except that: –have member functions –are capable of inheriting from parent classes Data members are the data components. Member functions are the function components of a class. An instance of a class data type is an object. EEL 3801 – Lotzi Bölöni Review of Structures In C++, structure data types can be created directly through the struct tag. Members can be accessed through the: –dot operator if directly referenced (a variable) –arrow operator if referenced through a pointer. Can be dynamically allocated through the new operator. EEL 3801 – Lotzi Bölöni Disadvantages of Structures External programs can directly access the structure members. Initialization not required or permitted directly. Cannot be printed as a unit. Cannot be compared in their entirety - must be compared member by member. No inheritance. EEL 3801 – Lotzi Bölöni Structure Example struct Time { int hour; int minute; int second; } ; void printMilitary(const Time &); void printStandard(const Time &); main() { Time dinnertime; ...} See page 598 of textbook. EEL 3801 – Lotzi Bölöni Classes Defined similarly to a structure, with the exception that: –Uses the class keyword rather than struct. –Allows the inclusion of function prototypes inside class definition for member functions. –Can specify the access of its members: private: only accessible through member functions public: accessible to any part of the program that has access to its object. EEL 3801 – Lotzi Bölöni Example of a Class class Time { public: void setTime(int, int, int); void printMilitary(); void printStandard(); private: int hour; int minute; int second; }; EEL 3801 – Lotzi Bölöni Classes Now the functions used to print the time are included as member functions of the class data type Time. Note that the prototypes for the printing functions have no need to have the object passed to it, as they are part of it. The values of hr, min and sec are set by a member function, not by outsiders. EEL 3801 – Lotzi Bölöni Classes The data members are private, thus cannot be changed by outside functions (for now). This is called information hiding, and it is an important aspect of software eng’rg. Internal structure is of no concern to the class user. Internal modifications to the class are transparent to user of the class. EEL 3801 – Lotzi Bölöni Member Functions Member functions can be defined: – inside the class body (rather than just the prototype). Typically done when function body is short –outside the class body using the scope resolution operator (::) Done when definition is long and cumbersome preferable in most cases EEL 3801 – Lotzi Bölöni Types of Member Functions Access functions: Used to read or display private data for a class. Kept public. Predicate functions: Used to determine truth or falsity of certain class data members or other class states. For example, list is full. Utility functions: Used to carry our a task not directly related to private data members. Can be kept as private, as client has no need. EEL 3801 – Lotzi Bölöni Class Scope Variable and function names declared inside a class definition belong to that class’ scope So the :: operator must be used for defining member functions if outside the class def. This allows for other classes to have functions of the same name. Functions defined inside a class definition are automatically inline’d by the class. EEL 3801 – Lotzi Bölöni Class Scope Non-member functions have file scope. Within a class’s scope, all members can be referenced directly by name by the member functions. Outside a class’s scope, data members (that are public) are accessed only through a reference or a pointer to an object of that class. EEL 3801 – Lotzi Bölöni Class Scope Member functions have function scope within their class. –If member function defines a variable with same name as a variable with class scope, the classscope variable is hidden by the function-scope variable within the function scope. –Such a hidden class scope variables can be accessed with the scope resolution operator by preceding the operator with the class name. EEL 3801 – Lotzi Bölöni Class Scope –Hidden global variables can be likewise accessed from inside a class where another variable has the same name through the use of the unary scope resolution operator (i.e., the class name is omitted from before the operator) dinnerTime::hour vs ::hour EEL 3801 – Lotzi Bölöni Example #include <iostream.h> class Count { public: int x; void print() { cout << x << ‘\n’; } }; main() { Count counter; Count *ctrptr = &counter; Count &ctrref = counter; EEL 3801 – Lotzi Bölöni Example counter.x = 7; counter.print(); ctrref.x = 8; ctrref.print(); ctrptr->x = 10; ctrptr->print(); } EEL 3801 – Lotzi Bölöni Example The results obtained after running that program are: 7 8 10 Keep in mind that in this case, the data member x was made public. Thus, it was able to be accessed directly from main() through . or ->. This is not typical. EEL 3801 – Lotzi Bölöni Interface Class definitions are typically placed in a header (.h) file. Place the definition of the member functions as a source file (.cpp) to be compiled. That way, the customer can be given the object code for the .cpp file and not reveal the proprietary source code. EEL 3801 – Lotzi Bölöni Controlling Access to Members An important part of C++ and OOP. Outside access to a class’s data members and member functions can be controlled: –public: –private: –protected: Default mode is private: EEL 3801 – Lotzi Bölöni Controlling Access to Members Therefore, all members after class header and before next label are private: After each label, the access mode defined by that label applies until next label or }. Labels may be repeated, but that is rare. EEL 3801 – Lotzi Bölöni Controlling Access to Members private: members - can only be accessed by other members of the same class or those of a friend class (later). public: members can be accessed by any function in the program through the . or -> operators. Provide the services or public interfaces of that class. protected: (later - Chapter 19 - Inherit.) EEL 3801 – Lotzi Bölöni Controlling Access to Members Private members of a class, as well as the definitions of public member functions, are not accessible to the clients of a class. For the Time class defined previously: main() { Time t; t.hour = 7; // error - hour is private. t.printMilitary(); // no error } EEL 3801 – Lotzi Bölöni Good Practice A client may be a global function or another class’s member function. Keep all data members of a class as private. Keep all access to private data members through public member functions. Access private members through set() or get() member functions that are public. Can serve to check data validity and hide data forms from client. EEL 3801 – Lotzi Bölöni Controlling Access to Members Keep all public members together and first in the class definition. Keep all private members together and second in the class definition - explicit. C structures and unions have a public default access. For a structure, can be changed to private: and protected: (?). EEL 3801 – Lotzi Bölöni Private Functions Not all member functions have to be public. Functions used as utility functions by other member functions can be kept private. EEL 3801 – Lotzi Bölöni Constructor Functions Member functions that have the same name as the class. Invoked automatically when an instance of a class is created (an object). Data members cannot be initialized in the class definition - it is only an abstract class! Constructors can be used to initialize data members of a class instance. EEL 3801 – Lotzi Bölöni Constructor Functions Cannot return anything. May be overloaded. Can have arguments passed to it. Such arguments can be specified in the declaration of the instance level object, to the right of the object name and within parentheses, but before the semicolon. EEL 3801 – Lotzi Bölöni Constructor Functions Can contain default arguments - values placed in the prototype itself which sets the value of each of the arguments if no other values are specified when the instance level object is created. If no constructor function is defined, compiler creates a default constructor. Default constructor does nothing useful. EEL 3801 – Lotzi Bölöni Example - Constructor Functions class Time { public: Time(int=0, int=0, int=0); void setTime(int, int, int); void printMilitary(); void printStandard(); private: int hour; int minute; int second; }; EEL 3801 – Lotzi Bölöni Example - Constructor Functions Time::Time(int hr, int min, int sec) { hour = (hr>=0 && hr <24) ? hr : 0; minute=(min>=0 && min<60) ? min : 0; second=(sec>=0 && sec<60) ? sec : 0; } The constructor above ensures validity of initialized value. Sets to 0 if hr, min or sec not specified, EEL 3801 – Lotzi Bölöni Example - Default Arguments main() { Time t1, t2(2), t3(21,34); Time t4(12,25,42), t5(27,74,99); t1.printMilitary(); t1.printStandard(); t2.printMilitary(); t2.printStandard(); EEL 3801 – Lotzi Bölöni Example - Default Arguments t3.printMilitary(); t3.printStandard(); t4.printMilitary(); t4.printStandard(); t5.printMilitary(); t5.printStandard(); } EEL 3801 – Lotzi Bölöni Example - Default Arguments For t1: 00:00:00 12:00:00 midnight For t2: 02:00:00 2:00:00 AM For t3 21:34:00 9:34:00 PM EEL 3801 – Lotzi Bölöni Example - Default Arguments For t4: 12:25:42 12:25:42 PM For t5: 00:00:00 12:00:00 midnight (values were illegal, so they were set to 0) EEL 3801 – Lotzi Bölöni Destructors Have same name as class but with a tilde ~ in front. Invoked automatically when class instance leaves scope (is deleted). Does not per se delete the object, but performs termination housekeeping. Has no parameters and returns no value. Only one per class & cannot be overloaded. EEL 3801 – Lotzi Bölöni Destructors Not used with simple classes. Used when dynamically allocated memory must be deleted. Called when their object leaves scope. EEL 3801 – Lotzi Bölöni Things to Not Do Do not design a public: member function to return a reference to a private: data member. This compromises the integrity of the data member, since a reference is an alias, so that anything we do to it we do to the original variable. See Textbook pages 626 to 629. EEL 3801 – Lotzi Bölöni Constant Objects and Functions Preceding the class object instantiation with the operator const will make the object a constant object. This means that no member function will be allowed to be called - rather harsh!! But often, the programmer only means to disable changing the values of the members, and not prohibiting get access to data. EEL 3801 – Lotzi Bölöni Constant Objects and Functions To provide access, but not modification rights for a particular object: –the programmer may declare const member functions. –These cannot modify the object. –Only these can operate on const objects. –But this can be tricky: EEL 3801 – Lotzi Bölöni const Functions A member function is specified as const by doing both: –specifying it as const in its declaration in the class, and –inserting the keyword const in its definition after the function’s parameter list and before the left brace begins the function’s body. A const member function can be overloaded with a non-const version EEL 3801 – Lotzi Bölöni const Functions Example: class Whatever { . . int getvalue() const }; int Whatever::getvalue() const {return private_data} EEL 3801 – Lotzi Bölöni Initialization of const Objects Constructor functions in a const object must be allowed to modify the data members, as they must be somehow initialized. Constructors need not be const. But since the values of a const object cannot be modified by assignment: A member initializer must be used. EEL 3801 – Lotzi Bölöni Member Initializers Used with Constructor member function. Use the notation: : initialized_variable(init_val) This should be done after the parameter list but before the function body opening brace of the Constructor member function. EEL 3801 – Lotzi Bölöni Example of Initializer class Increment { public: Increment(int c=0, int i=1); void addinc() {count += increment;} void print() const; private: int count; const int increment; }; Increment::Increment(int c, int i) : increment(i) {count = c} } EEL 3801 – Lotzi Bölöni Potential Errors in const Objects –Defining as const a member function that modifies a data member of a non-const object. –Defining as const a member function that calls a non-const member function. –Calling a non-const member function for a const object. –Attempting to modify a const object EEL 3801 – Lotzi Bölöni Nested Classes Classes can be members of other classes. This is referred to as composition. Straight forward, except at initialization. When an object enters scope, its constructor is immediately invoked to initialize it. Member objects are constructed before their enclosing objects are constructed. EEL 3801 – Lotzi Bölöni Example of Nested Classes The “member” object’s parent class class Date { public: Date(int=1, int=1, int=1900); void print() const; private: int month; int day; int year; int checkDay(int); }; EEL 3801 – Lotzi Bölöni Example of Nested Classes The Constructor Function Date::Date(int mn, int dy, int yr) { month = (mn > 0 && mn < 12) ? mn : 1; year = yr; day = checkDay(dy); // validates day } EEL 3801 – Lotzi Bölöni Example of Nested Classes The enclosing class: note the 6 int args class Employee { public: Employee(char *, char *, int, int, int, int, int, int); void print() const; private: char lastname[25]; char firstname[25]; Date birthdate; Date hiredate; }: EEL 3801 – Lotzi Bölöni Example of Nested Classes Now, for the Constructor function: Employee::Employee(char *fname, char *lname, int bmonth, int bday, int byear, int hmonth, int hday, int hyear) : birthdate(bmonth, bday, byear), hiredate(hmonth, hday, hyear) { strncpy(firstname, fname, 24); firstname[24] = ‘\0’; strncpy(lastname, lname, 24); lastname[24] = ‘\0’; } EEL 3801 – Lotzi Bölöni Friend Functions and Classes A function that is not a member function of a particular class, but which has access to private and protected members of that class is called a friend function. A friend class is one all of whose functions have access to another class’s private (and protected) members. EEL 3801 – Lotzi Bölöni Friend Functions and Classes “Friendship” is granted, not taken. The class giving friend privileges must declare the friend class to be a friend: For class B to be a friend of class A, class A must declare that class B is its friend. “Friendship” is neither symmetric or transitive EEL 3801 – Lotzi Bölöni Friend Functions and Classes To declare such a friend function: –precede the function prototype in the friend class definition with the keyword friend. –Define the function outside the friend class, with no scope resolution operator. To declare class A as a friend of class B, place a declaration of the form friend class A as a member of class B. EEL 3801 – Lotzi Bölöni Friend Functions and Classes The labels public:, private: and protected: do not affect the friend declaration. Therefore, it does not matter where the friend declaration is placed. EEL 3801 – Lotzi Bölöni Example of Friends class Count { friend void setx(Count &, int); public: Count() { x = 0; } void print() const { .. } private: int x; }; void setx(Count &c, int val) { c.x = val; // no need for set() func } EEL 3801 – Lotzi Bölöni Friend Functions and Classes Note that in the previous example, the object instance of the “friendly” class is passed to the friend function. A function can be a friend of more than one class, but a member of at most one class. Friend classes are much less common than friend functions EEL 3801 – Lotzi Bölöni Friend Classes class Parttime; class Employee { public: friend class Parttime; private: char name[30]; int x; }; The friend class can be put anywhere. EEL 3801 – Lotzi Bölöni The This Pointer Every object has a pointer, called the this pointer, that points to itself. It is needed because only one copy of an class’s member function exist. No copies are made for each object instantiated. Data members, however, are cheaper, so each object has their own data members. EEL 3801 – Lotzi Bölöni Static Data Members Allows one data member of one class to be shared by all object instances of that class. Seem like global variables but have class scope. Can be public, private or protected. See page 661-665 of Deitel & Deitel for details. EEL 3801 – Lotzi Bölöni