Reusing Code in C Hasa relationship Classes with

  • Slides: 43
Download presentation
Reusing Code in C++ • • Has-a relationship Classes with member objects(containment) The valarray

Reusing Code in C++ • • Has-a relationship Classes with member objects(containment) The valarray template class Private & protected inheritance Multiple inheritance Virtual base class Template specializations

Classes with object members • A student class – A name (string class) –

Classes with object members • A student class – A name (string class) – A set of quiz scores – A fixed-size array? dynamic memory allocation? – An array-of-double

The valarray class

The valarray class

The Student class design • Containment (composition, layering) is a has-a relationship • Program

The Student class design • Containment (composition, layering) is a has-a relationship • Program studentc. h, studentc. cpp, use_stuc. cpp

Private inheritance • With private inheritance, public and protected members of the base class

Private inheritance • With private inheritance, public and protected members of the base class become private members of the derived class • Program studenti. h, studenti. cpp, use_studi. cpp

Containment or private inheritance • Has-a relationship can be generated by containment or private

Containment or private inheritance • Has-a relationship can be generated by containment or private inheritance • In general, it is easy to use containment to build up a “has-a” relationship • Private inheritance provides some privileges, such as accessing protected member, or redefining virtual function, which can not be implemented by containment

Containment or private inheritance • We should use containment to model a has-a relationship

Containment or private inheritance • We should use containment to model a has-a relationship • Use private inheritance if the new class needs to access protected members in the original class or if it needs to redefine virtual functions

Varieties of inheritance

Varieties of inheritance

Redefining access with using • Public members of a base class become protected or

Redefining access with using • Public members of a base class become protected or private when one uses protected or private derivation

Multiple inheritance • Program worker 0. h, worker 0. cpp, worktest. cpp

Multiple inheritance • Program worker 0. h, worker 0. cpp, worktest. cpp

Ambiguous inheritance • Program worker. h, worker 0. cpp, worktest. cpp // point out

Ambiguous inheritance • Program worker. h, worker 0. cpp, worktest. cpp // point out the ambiguities

Type conversion class Singing. Waiter: public Singer, public Waiter { }; Singing. Waiter ed;

Type conversion class Singing. Waiter: public Singer, public Waiter { }; Singing. Waiter ed; Worker *pw = &ed; // ambiguous Worker *pw 1 = (Waiter *) &ed; // the Worker in Waiter Worker *pw 2 = (Singer *) &ed; // the Worker in Singer

Inherit two base-class objects

Inherit two base-class objects

Virtual base classes class Singer : virtual public Worker { }; class Waiter :

Virtual base classes class Singer : virtual public Worker { }; class Waiter : public virtual Worker { }; class Singing. Waiter: pubic Singer, public Waiter { …};

Using virtual base class • If a class has an indirect inherit virtual base

Using virtual base class • If a class has an indirect inherit virtual base class, a constructor for that class should explicitly invoke a constructor for the virtual base class unless all that is needed is the default constructor for the virtual base class – Singing. Waiter(const Worker &wk, int p=0, int v=Singer: : other) : Waiter(wk, p), Singer(wk, v) { } // flawed – Singing. Waiter(const Worker &wk, int p=0, int v=Singer: : other) : Worker(wk), Waiter(wk, p), Singer(wk, v) { } // ok

Indicate which method • Multiple inheritance can result in ambiguous calls Singing. Waiter newhire(“Elise

Indicate which method • Multiple inheritance can result in ambiguous calls Singing. Waiter newhire(“Elise Hawks”, 2005, 6, soprano); newhire. Show(); // ambiguous newhire. Singer: : Show(); // use Singer version void Singing. Waiter: : Show() // best way to do it { Singer: : Show(); }

Problems shooting void Worker: : Show() const { cout << “Name: ” << fullname

Problems shooting void Worker: : Show() const { cout << “Name: ” << fullname << “n”; cout << “Employee ID: ” << id << “n”; } void Waiter: : Show() const { Worker: : Show(); cout <<“Panache rating: ” << panache << “n”; } void Head. Waiter: : Show() const { Waiter: : Show(); cout << “presence rating: ” << presence << “n”; } void Singing. Waiter: : Show() { Singer: : Show(); } // fail due to ignoring Waiter void Singing. Waiter: : Show() { Singer: : Show(); Waiter: : Show(); } // call Worker: : show() twice

Using modular approach void Worker: : Data() const { cout << “Name: ” <<

Using modular approach void Worker: : Data() const { cout << “Name: ” << fullname << “n”; cout << “Empolyee ID: ” << id << “n”; } void Waiter: : Data() const { cout << “Panache rating: ” << panache << “n”; void Singer: : Data() const { cout << “Vocal range: ” << pv[voice] << “n”; } void Singing. Waiter: : Data() const { Singer: : Data(); Waiter: : Data(); } void Singing. Waiter: : Show() const { cout << “Category: singing waitern”; Worker: : Data(); } • Program workermi. h, workermi. cpp, workmi. cpp

Multiple inheritance synopsis • A derived class with an indirect virtual base class should

Multiple inheritance synopsis • A derived class with an indirect virtual base class should have its constructors invoke the indirect baseclass constructors directly, which is illegal for indirect non-virtual base classes • Name ambiguity is resolved via the dominance rule

Class templates • Inheritance and containment aren’t always the solution when you want to

Class templates • Inheritance and containment aren’t always the solution when you want to reuse code • Drawbacks of different datatype – Edit header file each time when one changes the type – One can use the technique to generate just one kind of the class per program • C++ class template provide a better way to generate generic class declaration • C++’s Standard Template Library (STL)

The original Stack class

The original Stack class

Using a class template Stack<int> kernels; // create a stack of int Stack<string> colonels;

Using a class template Stack<int> kernels; // create a stack of int Stack<string> colonels; // a stack of string objects Template<class T> void simple(T t) { cout << “n”; } … simple(2); // generate void simple(int) simple(“two”); // generate void simple(char *) • Program stacktp. h, stacktem. cpp

Stack pointer – incorrect version Stack<string> s; // original stack Stack<char *> st; //

Stack pointer – incorrect version Stack<string> s; // original stack Stack<char *> st; // create a stack for pointers-to-char string po; • Three versions to replace “string po; ” 1. char *po; cin >> po; // error 2. char po[40]; // template <class Type> // bool Stack<Type>: : pop(Type &item) // { …; item = items[--top]; … } // item is Lvalue, cannot be array name 3. char *po = new char[40]; // push to the same address, and pop the same address value // pop outcome is always the last push in data

Correct version • Program stcktp 1. h, stkoptr 1. cpp

Correct version • Program stcktp 1. h, stkoptr 1. cpp

Array template • Template is usually used in container class Array. TP<int, 5>, 10>

Array template • Template is usually used in container class Array. TP<int, 5>, 10> twodee; int twodee [10][5]; • Program arraytp. h, twod. cpp • Generate 2 separate class declarations • Just one class declaration through constructor

Template versatility

Template versatility

Using one than one type parameter • Program pairs. cpp

Using one than one type parameter • Program pairs. cpp

Template specializations • Template specializations – Implicit instantiation – Explicit specialization • Partial specialization

Template specializations • Template specializations – Implicit instantiation – Explicit specialization • Partial specialization

Implicit instantiation • The compiler doesn’t generate an implicit instantiation of the class until

Implicit instantiation • The compiler doesn’t generate an implicit instantiation of the class until it needs an object

Explicit instantiation • Generate Array. TP<string, 100> class • The compiler generates the class

Explicit instantiation • Generate Array. TP<string, 100> class • The compiler generates the class definition, including method definitions, even though no object of the class has yet been created or mentioned

Explicit specialization • An explicit specialization is a definition for a particular type of

Explicit specialization • An explicit specialization is a definition for a particular type of types that is to be used instead of the general template • A specialized class template definition has the form • To provide a Sorted. Array template specialized for the const char * type, using the current notation

Partial specializations • C++ allows for partial specializations, which partially restrict the generality of

Partial specializations • C++ allows for partial specializations, which partially restrict the generality of a template

Partial specializations • Providing a special version for pointers • Making a variety of

Partial specializations • Providing a special version for pointers • Making a variety of restrictions • The compiler would make the following choices

Member templates • Member templates – Program tempmemb. cpp • Templates as parameters –

Member templates • Member templates – Program tempmemb. cpp • Templates as parameters – Program tempparm. cpp

Template classes and friends • Template class can have friends • 3 types of

Template classes and friends • Template class can have friends • 3 types of template friends – Non-template friends – Bound template friends • The type of the friend is determined by the type of the class when a class is instantiated – Unbound template friends • All specializations of the friend are friends to each specialization of the class

Non-template friend functions to template classes • counts() function is a friend to Has.

Non-template friend functions to template classes • counts() function is a friend to Has. Friend<int> or Has. Friend<string>

Bound template friends • The compiler would replace the template parameter T with int,

Bound template friends • The compiler would replace the template parameter T with int, giving in this form

Bound template friends • The report() function is not itself a template function, it

Bound template friends • The report() function is not itself a template function, it just has a parameter that is a template • Need to define explicit specializations for the friends one plans to use

Template class with non-template friends • Program frnd 2 tmp. cpp

Template class with non-template friends • Program frnd 2 tmp. cpp

Bound template friend functions to template classes • Bound template friend involves three steps

Bound template friend functions to template classes • Bound template friend involves three steps • Step 1, declare each template function • Step 2, declare the templates again

Bound template friend functions to template classes • Step 3, declare an object of

Bound template friend functions to template classes • Step 3, declare an object of a particular specialization • The compiler substitutes int for TT and generates the following class

Template friend to a template class • Program tmp 2 tmp. cpp

Template friend to a template class • Program tmp 2 tmp. cpp

Unbound template friend functions to template classes • show 2(hfd, hfi 2) gets matched

Unbound template friend functions to template classes • show 2(hfd, hfi 2) gets matched to this specialization • Program manyfrnd. cpp