CS120 - Week 11 ------------------ - implicit/explicit type conversions with classes - conversion constructors (single param) - convert into class type - conversion (cast) operator - convert from class type - cannot be friend, must be non-static member - do not specify return type - it is type of conversion - if defined, can be called implicitly Rational :: operator double() const; // Rational to real number Fraction :: operator Rational() const; // Fraction to Rational - explicit constructor calls to create constant temporary object - use Classname(params) - eg: Rational r2 = 3 + Rational(3,4); INHERITANCE ---------------------------------------------------------------- - HAS-A vs. IS-A relationships - has-a is for composition, aggregation - differences? - is-a means inheritance - do a bunch of class diagrams for various problems!! - Banking (main example - use prepared code) - Points (use condensed code) - Shapes - Furniture - Palm Pilot/Planner (java lab) - I/O classes - in general: class classname : access (private default) baseclassname - if access is public, it means derived class can access public members of baseclass, but not private - if access is private, nonstatic members of base class become private members in derived class - constructors for baseclass are executed before constructors for derived class members (destructors are opposite) - using protected specifier - in base class: protected means things in class and any derived classes can access it directly, things outside class can't - can be used to restrict access to only derived class (making base an abstract class with no public members) - can be used to give access to derived class for something that would otherwise be private - more on private inheritance (not so common) - use to restrict access to base class functions that have no meaning for derived class - individual base class members can be granted public access with a "using" access declaration - constructors, destructors and assignment are not inherited! (remember: defaults are created unless you specify them) - ambiguity with multiple inheritance exists if base member functions have the same name, regardless of signatures VIRTUAL -------------------------------------------------------------------- - using virtual functions in base classes (virtual.cpp) - using pointers to base and derived objects (virtual.cpp) - type conversions between base and derived objects - virtual functions - used to resolve ambiguity with inheritance - used for dynamic method binding with ptrs & inheritance - creates late binding or run-time binding of methods (decision which function version to use made at run-time) - any non-static member function except constructor can be virtual (sometimes virtual destructors are required) - do not need to say 'virtual' in derived classes (optional) - should have virtual destructor (even if empty) in base class with virtual functions because want the derived class destructors to be called if they exist - destructors not inherited, so should make one for each derived class, especially if memory allocation is involved - function signature is name, and argument types and const-ness - OVERRIDING is what happens when derived and base have the same function (same name, param types, return types, const-ness) and the base function is virtual - OVERLOADING is when function has same name (different types) as another in the same scope - HIDING is when derived function has same name (regardless of arguments) as non-virtual base function - illegal for function in derived class to have same signature as virtual function in base with different return type - if functions in base and derived classes have the same signature, can use the scope resolution op (::) to get to function in the base class (the derived class is default) - virtual base classes - make *all* members protected or private - can only be accessed through derived class, not from outside (eg, main) Conversions btwn base & derived classes ----------- - derived class objects can be passed as base class objects (slicing) - derived class references can be passed as base class references - base class pointers (bptr) can also point to derived class objects - static base type of bptr is ptr to base (base *) (ptr type) - dynamic type of *bptr is derived (type of referrent) - dynamic type of bptr is ptr to derived (derived *) - base from derived conversions are implicit (smaller from larger class) - base into derived conversions must be explicit - bc doesn't make sense if conversion uses members not in the base class - type compatibility - can assign a derived object to a base object - can pass a derived object to a base parameter - can NOT go the other way around - will slice the extra members of the derived object - if pass by reference, will not slice class Item { // ... }; class Student : public Item { // ... }; class Collection { public: void Append(const Item * ip); Item * Get() const; }; main() { const int count = 10; Collection studentlist; Student *sptr; for (int i=0; i base } // no slicing bc pointer is passed sptr = (Student *) studentlist.Get(); // explicit conversion base -> der } - better approach would be to inherit student collection from collection and redo the methods requiring type casting in studentcollection - BASE CLASS w/MULTIPLE INHERITANCE - used in conjunction with multiple inheritance - causes some ambiguity when functions have multiple inheritance paths - ambiguity can be resolved by stating 'virtual' inheritance when declaring derived class - eg: - person base class - student derived class, employee derived class - grad assistant multiply derived class Person { public: String & GetSSN(); private: String SSN; }; class Employee : public virtual Person { }; class Student : public virtual Person { }; class GradAsst: public Employee, public Student { }; GradAsst gs1; cout << gs1.GetSSN(); // not ambiguous now ABSTRACT BASE CLASS (like interface in Java) -------------------------------------------------------------------- - defining abstract base classes with pure virtual functions (abstract.cc) - abstract means can't have any instances of the class - designated by containing at least one PURE virtual function - pure virtual function: virtual functionprototype = 0; // in base header NO definition of function in base class - each dervied class must have its own definition of every pure virtual function in the base class - if no definition in a derived class, derived class is also then an abstract base class - can mix non-virtual, virtual and pure virtual in one class - abstract base class can have data members - data members may need to be protected access if the pure virtual functions in the derived classes access them - great for enforcing common interface among related (derived) classes - instances cannot be created - as variable declarations - as pass by value formal arguments - dynamically with new - pointers to abstract types may be created - must point to derived object instances - references to abstract types may be function arguments - usefulness: array of pointers to base objects to form collection of related but different class objects - eg: do abstract.cc example - finish BankAccount classes