CS 541 Lecture -*- Outline -*- * C++ Classes These are the data abstraction mechanism. Recall that a class is a factory for making objects... in this lecture classes without inheritance. ** basics *** a class is a kind of struct -------------------- C++ CLASSES class Person { enum { maxNameLength = 20 }; char name[maxNameLength]; int employeeNumber; }; -------------------- *** class name is a type name Person is a type name Person not equal to any other type name (by name type check) so a class isn't just a module as in Modula or Ada *** can't initialize in declarations of data members so can't say const int maxNameLength = 20; -------------------- class Error { // member can't be exactly class type Error this_is_one; }; --------------------- *** Classes can be mutually recursive --------------------- CLASSES CAN BE MUTUALLY RECURSIVE class Exp; class Factor; class Term; class Exp { // ... }; class Factor { // ... }; class Term { // ... }; --------------------- *** information hiding A class is a scope --------------------- INFORMATION HIDING class Foo { friend class MyFriend; friend int trustedFunction(); public: // decls clients can see // ... private: // decls hidden from clients // ... }; --------------------- the friend decls are not declarations of members, but directives other decls (of data and functions) are called members the class MyFriend can see Foo's private parts, as can trustedFunction as in real life, friendship is NOT transitive a member fun of one class can be a friend of another class. the default, if neither public: or private: is used, is private: a struct is a class with all members public ** Example *** typical file usage members can be defined in class definition (e.g., consts, inline) or can be defined in separate file ----------------- EXAMPLE CLASS In file Date.h: class Date { public: Date(int d = 0, int m = 0, int y = 0); int month() { return mo; } int day() { return dy; } int year() { return yr; } void next(); private: int mo, dy, yr; }; In file Date.cc: #include "Date.h" extern Date today; Date::Date(int d, int m, int y) { dy = (d != 0) ? d : today.dy; mo = (m != 0) ? m : today.mo; yr = (y != 0) ? y : today.yr; } void Date::next() { dy++; // ... } ----------------- Notes: can access private parts of other objects of the same type. as in Date::Date. The Date operation is a constructor. It has default arguments. the job of the constructor code is merely to initialize the data members. Storage allocated by client. constructors can ensure that all objects of that class are initialized syntax: same as class name, e.g., Date() can have default arguments, can be overloaded Member functions with implementations in the definition are inlined. **** file usage separate class declaration from implemenation def in .h file implementation (member funs) in .cc file generally requires recompilation of clients! since may allocate variables (on stack) so need to know size (as in Ada) when size of objects changes, need to recompile clients must recompile member function implementations when change class decl. why? efficiency (of allocation and access) compatibility with C structures *** Scope of declarations of class members includes implementations of member functions (see body of Date::Date above) can be used after . or -> e.g., mydate.set mine->set function members can be referred to using scope open operator when class name is visible e.g., Date::next *** Construction and Message passing -------------------- A MAIN PROGRAM #include #include "Date.h" Date today(23, 4, 1993); int main() { Date my_bday = Date(4,11,1957); my_bday.next(); Date* mine = &my_bday; mine->next(); cout << (mine->day()) << "\n"; return 0; } ------------- today is initialized by calling the constructor, as is the temporary Date(4,11,1957) my_bday is initialized by the copy constructor, means a memberwise assignment by default the copy contructor would be a function with prototype Date(const Date&) note: initialization is not the same as assignment. ** self-reference "this" a pointer to the receiver of the message available within an implementation of a function member, not generally needed (since can refer to members directly) but useful if need to refer to whole object ------------ SELF-REFERENCE BY THE this POINTER class Dlink { public: void append(Dlink*); //... private: Dlink* pre; Dlink* suc; }; void Dlink::append(Dlink *p) { p->suc = suc; p->pre = this; suc->pre = p; suc = p; } ------------ ** Constructors, Destructors *** allocation and deallocation -------------------- ALLOCATION AND DEALLOCATION { // allocate on stack Date july4(4,7,1776); // allocate on heap Date *dp = new Date(3,5,1992); Date *(da[10]) = new Date[10]; // explicit deallocation delete dp; delete da[]; // implicit deallocation of july4 } -------------------- *** manager functions ----------------- MANAGER FUNCTIONS destructors: named ~ClassName (e.g., ~Date()) implicitly called by delete tidy up before space deallocated space for *this deallocated by C++ no formals constructors: named ClassName (e.g., Date) implicitly called by new and var decls space for *this allocated by C++ initialize members after space allocated can be overloaded ----------------- constructors can be overloaded (and often are) **** construction and destruction of static objects constructors called before main() is run arguments must be static expressions called in order they appear in a file destructors called after main() returns or exit() is called (but not abort) called in reverse order of constructors **** Construction of classes that contain other class instances as members (not pointers to other class instances) ------------------ CONSTRUCTION OF OBJECTS WITH MEMBERS FROM OTHER CLASSES class School_Year { public: school_year(Date, Date); // ... private: Date start_date; Date end_date; //... }; School_Year::School_Year (int sd, sm, sy, ed, em, ey) : start_date(sd, sm, sy), end_date(ed, em, ey) { // ... } ------------ the syntax : start_date(sd, sm, sy), end_date(ed, em, ey) calls the constructors for Date, and puts the results in the members if you want to have an array of objects: class must have no constructor or constructor without arguments **** copy constructor (omit if short on time) for class X has prototype X::X(const X &) if not given explicitly, then by default this is memberwise copy responsible for initialization Date bday = Date(4, 11, 1957) note this is different than assignment also responsible for copying actuals to formals, and result out **** assignment operator (omit if short on time) for class X has prototype X::operator=() if not given explicitly, then by default this is memberwise copy ** static members (omit if short on time) like class variables in Smalltalk declarations of members with "static" are shared by all members of a class (static extent) --------- class task { task* next; static task* task_chain; //... }; --------- can be either private or public (or protected) initialization explicit and can be done outside of class decl. task* task::task_chain = 0;