230 likes | 419 Views
Universitatea de Vest din Timişoara Facultatea de Matematică şi Informatică. Object Oriented Programming. Lect. Dr. Daniel POP. Course #3 Agenda. Classes in C++ (continued) Access control Constructors Destructor Self-reference
E N D
Universitatea de Vest din Timişoara Facultatea de Matematică şi Informatică Object Oriented Programming Lect. Dr. Daniel POP
Course #3 Agenda • Classes in C++ (continued) • Access control • Constructors • Destructor • Self-reference • Modifiers: static, const, mutable Object-Oriented Programming
Access Control • To implement the data hiding principle in C++, various level of access are defined for class members (data or functions): • private – accessible only to member functions and friends; • protected – accessible to member functions and friends + member functions and friends of derived classes; • public – accessible from everywhere. • Public members define the public interface of one class. • Example: class MyClass { int x; // private, by default public: int y, z; // public int f(); // public member function private: int w; // private data protected: int f(int, int); // protected member function }; void main(){ MyClassobj; obj.x = 10;// ERROR: Cannot access private members obj.f(); // OK! obj.f(1,1); // ERROR:Cannot access protected members } Object-Oriented Programming
Constructors (I) • Rationale: to prevent errors caused by non-initialized objects • Example: Date objects, a Stack with dangling pointer to its top element etc. • DEFINITION [Constructor] A member function of a class whose role is to initialize the class instances (objects). • Object creation process: • Memory allocation • Find an appropriate constructor • Call the constructor to initialize the object’s state after the data members have been previously constructed/initialized by calling their constructors • Q: Which member functions are the constructors? • A: The constructor name = class name • Characteristics of constructors: • The name = Class name • They have NO return value (Remark: void is a return value) • No pointers can be assigned to constructors (PMF pmf = &Date::Date; is illegal) • Except for the above constraints, constructors are handled as any other member function of a class (for example, they may have 0, 1 or more arguments, etc.) Object-Oriented Programming
Constructors (II) class Date{ int _day, _month, _year; void init(int day, int month, int year); public: // Constructors! Date(int day = 0, int month=0, int year=0); }; void f() { Date d3; // correct } • Example: class Date{ int _day, _month, _year; void init(int day, int month, int year); public: // Constructors Date(int day, int month, int year); Date(int day, int month); Date(int day); }; void f(){ Date d0 = Date(6, 10, 2003); // correct Date d1(1, 1); // correct Date d2(15); // correct Date d3; // ERROR: No appropriate constructor is found Date* pd = new Date(7, 10, 2003); // correct } #include “Date.h” Date::Date(int day, int month, int year) { _day = day ? day : today.day; _month = month ? month : today.month; _year = year ? year ? today.year; } Object-Oriented Programming
Constructors (III). Default Constructor • Constructor without arguments • Prototype: X(); • If a class has no constructors then the compiler generates a default constructor for that class that implicitly calls the default constructors for class’ members of class type and bases. • Remark: If a class has const or reference members then the default is not generated automatically because consts and references must be initialized. • Examples: class Date{ public: // default constructor Date(int day=0, int month=0, int year=0); }; class String { public: String(); // default constructor }; class Student { Date birthday; String name; // automaticlly generated default constructor that calls Date and String // defaults constructors }; class Date { public: // no default constructor is generated Date(int day); }; class Test { const int a; int& r; // no default constructor is generated }; Object-Oriented Programming
Constructors (IV). Copy Constructor • Constructor with one argument of type reference to its own class • Prototype: X(const X&); • const – indicates that the source object is not modified • It is called: • Declaration of an object like X obj = obj_source; • Passing an object as an argument to a function call func(X); WHY? • When a temporary object is created during expression evaluation • If it is not defined for one class, then the compiler automatically generates one that copies bit-by-bit the content of source object to destination object. • To prevent copying of objects, the copy constructor can be declared private (no implementation is needed). • To ‘deep’ copy complex objects, the copy-constructor is mandatory! (Examples in lab) • Examples: void g(Date d) { d.setDay(); } void f() { Date d(7, 3, 2007); // user-defined constructor Date d; // default constructor Date d2 = d; // copy constructor d2 = d; // NO copy constructor g(d); // copy constructor is called } class Date{ public: Date(int day=0, int month=0, int year=0);// default constructor Date(const Date& ref); // user-defined copy constructor void setDay(int day); }; Object-Oriented Programming
Constructors (V). Type Conversion Constructors • Scope: convert from one data type to a class (built-in type | user-defined-type class) • Prototype: X(Datatype); • Called in • declarations like X x = value; where value is a Datatype • function calls to cast the actual argument to required type class Date{ public: // … Date(char* str) ; // type-conversion constructor }; void g(Date d) { d.setDay(7); } void f() { Date d = “6/3/2007”; g(“This is tricky ;-)”); } class Double{ double val; public: Double(double v) { value = v; } } ; vod f(){ // three equivalent declarations Double obiect = 2.5; Double obiect = Double(2.5); Double obiect(2.5); } Object-Oriented Programming
Destructor • Rationale: to prevent errors caused by un-released objects (unreleased resources). • Example: Stack without freeing the memory used, File without closing the handle etc. • DEFINITION [Destructor] A member function of a class whose role is to release the class instances (objects) from memory. • Object destruction process: • Call the destructor function • Call destructors of data member • Free the memory • Q: Which member function is the destructor? • A: The destructor name = ~class name (i.e. ~X) • Characteristics of constructors: • Prototype: X::~X(); • They have NO return value (Remark: void is a return value) and they take no arguments. • No pointers can be assigned to destructor (PMF pmf = &Date::~Date; is illegal) • Except for the above constraints, destructor is handled as any other member function of a class. Object-Oriented Programming
Destructor (II) • A class can have at most one destructor. • The compiler generates an empty default destructor. • Example: class String { char* str; public: // Constructors String(char* psz=NULL); ~String(); }; void f(){ String s1; String s2=“We like C++;)”; String s3=s2; String* s4 = new String(“Do we?”); delete s4; // destructor is called } // destructors for s3, s2, s1 are called in this order String::String(char* psz) { if(psz==NULL) str=NULL; else { str = new char [strlen(psz)+1]; strcpy(str, psz); } } String::~String() { if(str!=NULL) delete [] str; } Try this & Explain the result! Object-Oriented Programming
Constructors & Destructor • Both, constructor and destructor can be explicitly called. NOT RECOMMENDED TO DO THIS! • Example void f(){ String s1; s1.String::String(“Explicit call”); s1.~String(); } • RECOMMENDATION: If a class has a pointer member, it needs a copy constructor, a destructor and an assignment operator (see operator overloading). Object-Oriented Programming
Self-Reference • Example: void f() { Date d; d.init(25,12,2007).getMonth(); } Date& Date::init(int day, int month, int year) { this->_day = day; // _day = day _month = month; // implicit use of this this->year = year; // year – makes possible // to use the same name // for members and args this++; // ILLEGAL: this is a const pointer return *this; } • => The prototype of init function should be: Date& init(int, int, int); • Each non-static member function knows what object it was invoked for and can explicitly refers to it using this keyword. • this is a pointer to the object for which the function was called • For non-const function its type is: X* const this; • For const function its type is: const X* const this; • Similar in Java (this), Smalltalk (self) or Simula (THIS). Object-Oriented Programming
Modifiers: static (I) • DEFINITON [static data member] A variable that is part of a class, yet is not part of an object of that class is called a static member. • There is exactly one copy of a static variable ‘shared’ by all objects of that class. • Static data member = global variable defined and accessible only in the scope of that class. • DEFINITION [static member function] A function that needs access to members of a class, yet doesn’t need to be invoked for a particular object, is called a static member function. • Static member function = global function defined and accessible only in the scope of that class. • Declaration of static members: • Accessing static members: static MemberDefinition; X::memberName; obj.memberName; • In order to clearly differentiate between static and non-static members + enhance code readability, the first (bold) syntax is recommended to be used. Object-Oriented Programming
Memory representation of static data. Modifiers: static (II) class Date{ int day, month, year; static Date today; // declare the static data member public: // … static void initToday(); }; Date Date::today; // create the static data member void Date::initToday() { time_t t; time(&t); tm* now = localtime(&t); day = now->tm_mday; // ERROR: whose day is this day? today.day = now->tm_mday; today.month = 1 + now->tm_mon; today.year = 1900 + now->tm_year; } int main(int, char*[]) { Date::initToday(); return 0; } • REMARKS: • static data members have to be defined/initialized somewhere (in the class definition they are only declared) • static member function DOES NOT receive this pointer • => the access to non-static members (data/function) is not possible from within static functions • Creation, initialization and access to static members are independent of objects existence. • Example: default date (today) in Date class Object-Oriented Programming
Modifiers: const class Date{ int day, month, year; static Date today; // declare the static data member public: //const, inline member function int getDay() const { day = 0 ; // ERROR: we’re in const function return day; } int getMonth() const { return month; } int getYear() const { return year; } }; int main(int, char*[]) { Date d; cout << d.getDay() << d.getMonth() << d.getYear(); return 0; } • Data members • Cannot be modified! • Useful to declare constants at class scope • Syntax: • Member functions: • Cannot modify the state of the object (i.e. data members) • Enhances the code’s clarity • Prevents accidental updates • When the function is defined outside its class, const suffix is required. • Syntax: const data_type name; ftype fname(arg_list) const; Object-Oriented Programming
Modifiers: mutable class Date{ int day, month, year; mutable string cache; // always changeable! mutable boolean validCache; // always changeable! public: // const member function string toString() const; }; string Date::toString() const { if(!validCache) { cache = compute_new_string_representation(); validCache = true; } return cache; } • Applies only to data members • Can always be modified, even from within const functions! • Useful for members that need to be changed in const functions and don’t represent the actual internal state of the object • Syntax: mutable data_type name; Object-Oriented Programming
Further Reading • [Pop, 2003] Daniel Pop – C++ Programming Language Lecture Notes • [Stroustrup, 1997] Bjarne Stroustrup – The C++ Programming Language 3rd Edition, Addison Wesley, 1997 [Chapter 10] Object-Oriented Programming