55
COMS W3101: Programming Languages (C++) Instructor: Austin Reiter Lecture 4

COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

COMS W3101: Programming Languages (C++)

Instructor: Austin Reiter

Lecture 4

Page 2: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Last Time

• std::string

• Deeper look at classes

– friend, operator overloading, this pointer

• Intro to Inheritance

Page 3: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Outline For Today

• Finish up Inheritance

• Intro to Polymorphism

• Templates

Page 4: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Inheriting Members

• One problem with inheritance is that a derived class can inherit data members and member functions it does not need or should not have – It is your responsibility to ensure your base class has the

appropriate capabilities for any derived class

• Remember that we use inheritance so we don’t have to “copy-and-paste” the same code over and over – If you change one, you might forget to change them all.

– Instead, just have somebody inherit from me if they want this functionality, and then make it specific to them if need be (i.e., virtual methods)

Page 5: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Base-class member access specifier

public

inheritance protected

inheritance private

inheritance

public public in derived class. Can be accessed directly by member functions, friend functions and nonmember functions

protected in derived class. Can be accessed directly by member functions and friend functions.

private in derived class. Can be accessed directly by member functions and friend functions.

protected protected in derived class. Can be accessed directly by member functions and friend functions.

protected in derived class. Can be accessed directly by member functions and friend functions.

private in derived class. Can be accessed directly by member functions and friend functions.

private Hidden in derived class. Can be accessed by member functions and friend functions through public or protected member functions of the base class.

Hidden in derived class. Can be accessed by member functions and friend functions through public or protected member functions of the base class.

Hidden in derived class. Can be accessed by member functions and friend functions through public or protected member functions of the base class.

Page 6: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism

• So far we’ve covered: – Classes – Objects – Encapsulation – Operator overloading – Inheritance

• Polymorphism – “Program in the general” – Enables us to write programs that process objects of

classes that are part of the same inheritance hierarchy as if they were all the base class of that hierarchy

Page 7: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism

• Conceptual Example: – We are studying several kinds of animals. Fish, Frog and Bird are animals which inherit from base class Animal. • Animal contains function move() and maintains animal’s location. • Each derived class implements their own move().

– We want to maintain an array of Animal* of the various derived class (from Animal)

– To simulate animal movements, we sent each object a move() message through the Animal*, even though each behaves differently depending on what type of animal it is. • The messages are sent generically, but each knows how to operate

appropriately • This is polymorphism.

Page 8: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism

• We can design very extensible systems (i.e., add new classes with little or no changes to the general portions of the program)

• The two underlying technologies of polymorphism are: – virtual functions

– Dynamic binding

• We can determine the type of an object at run-time (i.e., while it’s being executed “on the fly”, rather than when it gets compiled) – Runtime Type Information (RTTI)

– Dynamic Casting

Page 9: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism

• With polymorphism, one function can cause different actions to occur, depending on the type.

• Recall virtual methods, introduced last time – The polymorphism occurs when a program

invokes a virtual function through a base-class pointer or reference.

– C++ dynamically chooses the correct function for the class from which the object was instantiated.

– Area code example

Page 10: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism

• Polymorphic software is written independent of the types of objects to which messages are sent

• New types of objects that can respond to existing messages can be incorporated without modifying the base system.

Page 11: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Inheritance vs. Polymorphism

• Polymorphism comes from Inheritance

• When we speak of inheritance, we say we want to create new classes from existing classes. – In this way, we “inherit” features and behaviors

• Polymorphism says to take this concept one step further, and code generically. Use inheritance to promote extensibility. – As much as possible, we want to treat an object of a

derived class as if it is actually an object of the base class. • This isn’t too much of a leap. A derived class is-a base class!

• BUT, we cannot treat a base class as one of its derived classes.

Page 12: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Base-Class and Derived-Class Pointers

• A few ways to aim base-class pointers and derived-class pointers at base-class objects and derived-class objects: – Method 1:

Consider a base class called Base and a derived class called Derived. // Construct the derived object as usual Derived d; // Now get a pointer to it, but treat it as a // pointer to the base-class Base* dPtr = &d; // Call methods from Derived through Base dPtr->print(); This is calling Derived::print(),

and it’s using the Base class to do it. Note: this assumes there’s also a Base::print(), and they are virtual!

Page 13: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Base-Class and Derived-Class Pointers

• A few ways to aim base-class pointers and derived-class pointers at base-class objects and derived-class objects: – Method 1:

Note: the opposite is illegal: // Construct the base object as usual Base b; // Now get a pointer to it, but treat it as a // pointer to the derived-class Derived* bPtr = &b; COMPILER ERROR!

Page 14: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Base-Class and Derived-Class Pointers

• However, consider the following example: class Shape { public: Shape(const int N, const double* x, const double* y); virtual ~Shape(); virtual double area() = 0; // … }; class Circle { public: Circle(const int N, const double* x, const double* y) : Shape(N,x,y) {} virtual ~Circle() {} virtual double area(); double getRadius() const; // … }

Can I do this? Circle c(10,x,y);

Shape* pC = &c;

radius = pC->getRadius();

Page 15: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Base-Class and Derived-Class Pointers

• However, consider the following example: class Shape { public: Shape(const int N, const double* x, const double* y); virtual ~Shape(); virtual double area() = 0; // … }; class Circle { public: Circle(const int N, const double* x, const double* y) : Shape(N,x,y) {} virtual ~Circle() {} virtual double area(); double getRadius() const; // … }

Can I do this? Circle c(10,x,y);

Shape* pC = &c;

radius = pC->getRadius(); COMPILER ERROR! NO!

Page 16: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

virtual Functions

• With virtual functions, the type of the object being point to, not the type of the handle, determines which version of a virtual function to invoke

Base class Base Derived class Derived Both contain non-virtual functions print()

Base class Base Derived class Derived Both contain virtual functions print()

Derived d;

Base* dPtr = &d;

dPtr->print();

Base::print() called

Derived d;

Base* dPtr = &d;

dPtr->print();

Derived::print() called

Page 17: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

virtual Functions

• virtual functions are overridden in derived classes (i.e., redefined)

• Must have the same signature and return type (i.e., the prototype) – Once a function is declared virtual, it remains virtual all the way down the inheritance hierarchy, even if not explicitly declared virtual when a derived class overrides it. • However, you should declare it virtual at every level

anyways. It’s b/c in a complex hierarchy, your program may exhibit polymorphic behavior and you can’t see why b/c the virtual is implied.

Page 18: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

virtual Functions

• Choosing the appropriate function to call at execution time (rather than at compile time) is known as dynamic binding

– Think about this: input from a file or a user on the command line can actually change what kind of object gets allocated, used. This would be unknown at compile time!

Page 19: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Dynamic Binding int main()

{

Shape* c = NULL;

int choice;

cout << “Enter type of Shape to use: “;

cin >> choice;

switch (choice)

{

case 1:

c = new Rectangle();

break;

case 2:

c = new Triangle();

break;

case 3:

c = new Circle();

break;

}

c->draw();

delete c;

What c actually is underneath depends on what the user enters on the command line! Nonetheless, the appropriate draw() command will be invoked.

Page 20: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Static Binding

• However, when a virtual function is called by referencing a specific object by name and using the dot member-selection operator (i.e., squareObject.draw()), the function invocation is resolved at compile-time

– This is NOT polymorphic behavior!

– Therefore, dynamic binding with virtual functions occurs only off pointer and reference handles

Page 21: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Abstract Classes

• Usually we create classes which are intended to create objects of that type

• Sometimes it is useful to define classes from which you never intend to instantiate any objects. – These are called abstract classes.

– They are normally used as the base class in a hierarchy. They cannot be used to instantiate actual objects b/c they are incomplete. • The derived classes “fill-in the missing pieces”

Page 22: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Abstract Classes

• We use these to define an interface with which all deriving objects must adhere to for specific functionality

– But, it keeps a strict consistency in the hierarchy

• An inheritance hierarchy does not need an abstract base class, but they are very common.

Page 23: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Pure virtual Functions

• A class is made abstract by declaring one or more of its virtual functions to be “pure”

• A pure virtual function is specified by placing an “= 0” in its declaration, as in: virtual void draw() const = 0;

Page 24: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Pure virtual Functions

• The “= 0” is known as a pure specifier. • They do not provide implementations. • Every derived class MUST override all base-class

pure virtual functions – Failure to do so will result in a compilation error

• The difference b/w virtual functions and pure virtual functions is that the former has an implementation in the base class and overriding in derived classes is optional. – The latter requires it.

Page 25: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Pure virtual Functions

• Purely virtual functions are used when it doesn’t make sense for the base class to implement the function, but you want all derived classes to give meaning to that function

• Again, attempting to instantiate an abstract class directly is a compiler error! – But, you can use the abstract class as a base pointer to

objects of derived classes, as usual

• Failing to implement a pure virtual method in a derived class is a compiler error!

Page 26: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Polymorphism Performance

• As implemented with virtual functions and dynamic binding is efficient.

• Used as an alternative to switch logic programming

Page 27: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

dynamic_cast

• Up to now, we’ve been casting using “C-style” casting – The compiler trusts you know what you’re doing

when you cast from a derived class to a base class pointer

• The opposite is called downcasting, where we want to express the base class pointer as the derived class – There’s a way to tell if the downcast actually is

valid, called dynamic_cast

Page 28: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

dynamic_cast

• Recall the Shape example. Consider the following: // Construct derived classes as base class pointers, // as usual: Shape* s1= new Circle(); Shape* s2= new Rectangle(); // Let’s downcast the pointer correctly Circle* pCircle = dynamic_cast<Circle *>(s1); if (pCircle != NULL) cout << “Downcast worked!” << endl; // Let’s show a downcast that doesn’t work Triangle* pTriangle = dynamic_cast<Triangle *>(s2); if (pTriangle == NULL) cout << “Error! s2 is NOT a Triangle!” << endl;

Page 29: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

dynamic_cast

• If the downcast works, you get back a pointer to the derived class, as expected.

• If you try to downcast to the incorrect derived type, dynamic_cast returns a NULL pointer

• Why use this??

Page 30: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

dynamic_cast

Shape* shapes[] = {NULL, NULL, NULL};

shapes[0] = new Circle();

shapes[1] = new Rectangle();

shapes[2] = new Triangle();

// Check which element of shapes contains the Rectangle:

for (int i = 0; i < 3; i++)

{

Rectangle* pRectangle = dynamic_cast<Rectangle *>(shapes[i]);

if (pRectangle != NULL)

{

cout << “Rectangle is stored at element “ << i << endl;

}

}

Page 31: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates

• One of C++’s more powerful software reuse features

• Function templates and class templates enable you to specify an entire range of overloaded functions with a single code segment

• Example: write a single function template to sort an array. C++ will then generate separate function template specializations that will sort int arrays, float arrays, string arrays, etc.

Page 32: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates

• We will only introduce templates here, and go more in-depth in the last lecture when we study the Standard Template Library (STL)

Page 33: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

A Little History

• Templates were originally created to make it possible to create type-safe containers: vectors, lists, maps (STL—Lecture 6)

• However, people were finding they could do much more with them.

– The concept of generic programming: the ability to write code that is independent of the types of objects being manipulated.

Page 34: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Overloaded functions perform similar operations on different data types

• However, if the operations are identical for each type, we can use function templates to express the code more compactly and conveniently.

• You write a single function-template definition, and the data type is inferred by the calls to this function.

Page 35: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Begin with the keyword template, followed by a list of template parameters enclosed in angle brackets (<>).

– Each template parameter represents a type and must be preceded by interchangeable keywords class or typename: template <typename T>

template <class ElementType>

template <typename BorderType, typename FillType>

Specify the types of the arguments to the function, the return type of the function, and declaration of variables within the function

Page 36: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Begin with the keyword template, followed by a list of template parameters enclosed in angle brackets (<>).

– Each template parameter represents a type and must be preceded by interchangeable keywords class or typename: template <typename T>

template <class ElementType>

template <typename BorderType, typename FillType>

class or typename keywords actually mean “any built-in type or user-defined type”

Page 37: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Example: printArray template< typename T >

void printArray(const T* const array, const int count)

{

for (int i = 0; i < count; i++)

cout << array[i] << “ “;

cout << endl;

}

int a[5] = {1, 2, 3, 4, 5};

double b[7] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7};

char c[6] “HELLO”;

printArray(a, 5);

printArray(b, 7);

printArray(c, 6);

Here, the compiler tries to find a definition of function printArray that best matches the function call. For a, the first argument is int*, and so the compiler deduces replacing T with int would make this consistent

Page 38: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Example: printArray template< typename T >

void printArray(const T* const array, const int count)

{

for (int i = 0; i < count; i++)

cout << array[i] << “ “;

cout << endl;

}

int a[5] = {1, 2, 3, 4, 5};

double b[7] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7};

char c[6] “HELLO”;

printArray(a, 5);

printArray(b, 7);

printArray(c, 6);

Then, the compiler creates a specialization of printArray which expects an int array. It does the same for double and char (i.e. 3 separate specializations of printArray)

Page 39: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• We said the template parameter may be a pre-defined type or a user-defined type. – A common error is a template function using operators (i.e., ==,

+, <=) with objects of that class type, but forgetting to overload those operators for your user-defined type. This results in a compiler error

• In the previous example, the template mechanism saves you from having to write 3 separate overloaded functions, all with the same code: void printArray(const int* const, const int); void printArray(const double* const, const int); void printArray(const char* const, const int);

Page 40: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Function Templates

• Think of function templates and function overloading as being closely related

• The function template specializations generated from a function template all have the same name and the overloading mechanism is used by the compiler underneath the hood to invoke the proper function

Page 41: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Class Templates

• Class templates allow for type-specific versions of generic classes to be instantiated – Ex: think about our Matrix class. We required the

underlying data type to be double. But, templates would allow us to define “any Matrix” and provide different instantiated matrices with types int, float, short, etc., all with the same behavior

• Again, you only write one class template definition – Each time an additional class-template specialization

is needed, the compiler writes the source code for the specialization required

Page 42: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Class Templates

• Example: stacks – A stack is a data structure into which we can insert

items at the top and retrieve those items in a “last-in, first-out” order.

– Think of a pile of plates. As we stack them one on top of another, when we want to retrieve a plate from the pile it will be the last one pushed onto the pile. This is called popping the stack. • The first plate that was pushed will be the last one popped.

– We want to define a stack concept independent of the type of the items in the stack. Let’s look at the code…

Page 43: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Class Templates

• There are 2 constraints for nonfundamental data types used with our Stack class template: – They must have a default constructor, b/c we use new

for a data array in our constructor – They must support the assignment operator=, for

when we push/pop elements

• Each member function definition of a class template is a function template. – Therefore each definition must begin with:

template< typename T >

Page 44: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Class Templates

• Therefore each class template member definition looks like a conventional function template definition. – The only difference is that the Stack element type

is always listed generically as type parameter T. – The binary scope resolution operator (::) is used with

class template name Stack<T> to tie each member definition to the class template’s scope: template< typename T > bool Stack<T>::push(const T& pushValue) { // … }

Page 45: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Class Template

• When we instantiated a Stack<double> type, the statement: stackPtr = new T[size] in the constructor of the class template is changed to: stackPtr = new double[size] in the compiler-generated class template specialization version of the Stack with type T = double. And similarly for the Stack<int> type.

Page 46: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Stack Class Template

• For our driver program, we had identical code to test the class because we wanted one double Stack and one int Stack.

• Let’s use templates to test the class template using a function template!

– See main2.cpp example

Page 47: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Nontype Parameters

• Our template Stack uses only a single parameter in the template header

• It’s also possible to use nontype template parameters, which can have default arguments and are treated as consts!. – For example, we could take the number of elements of the Stack as

a parameter as follows: template< typename T, int elements > Then a declaration such as: Stack< double, 100> doubleStack; would instantiate a double stack of 100-elements (rather than through the constructor)

Page 48: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Nontype Parameters

• One advantage of this is we can avoid using new and delete, b/c elements is a constant integer.

– Therefore we can have a private data member: T stackData[elements]; // array to hold Stack contents

However, this loses the dynamic nature of the Stack, but in STL we adjust the Stack to grow/shrink dynamically and this becomes a non-issue.

Page 49: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Default Types for Class Templates

• In addition, a type parameter can specify a default type. – For example:

// Defaults to string type if non given template< typename T = string > This might specify that a Stack contains string objects by default. Then a declaration such as: Stack<> stringStack; could be used to instantiate a Stack class template specialization of strings named stringStack. It’s just like: Stack<string> stringStack;

Page 50: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Explicit Specialization

• In some cases, it may not be possible to use a particular type with a class template. – For example, the Stack template requires user-defined types

to provide a default constructor and assignment operator. – If a user-defined type will not work with our Stack template

or requires customized processing, you can define an explicit specialization of the class template for a particular type.

– Consider a class Employee, and we want to form a new class with the name Stack<Employee>: template<> class Stack< Employee > { // body of class definition };

This would be a complete replacement for the Stack class template that is specific to type Employee. It does not use anything from the original class template and can even have different members

Page 51: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates and Inheritance

• A class template can be derived from a class-template specialization

• A class template can be derived from a nontemplate class

• A class-template specialization can be derived from a class-template specialization

• A nontemplate class can be derived from a class-template specialization

Page 52: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates and Friends

• We know that functions and classes can be declared as friends of nontemplate classes

• With class templates, friendship can be established b/w a class template and: – A global function

– A member function of another class (possibly a class-template specialization)

– An entire class (possibly a class-template specialization)

Page 53: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates and Friends

• We have assumed that a class template definition named X with a single type parameter T, as in: template< typename T > class X Under this assumption, we can make a friend function of every class template specialization for class X. To do this, use a friendship declaration as follows: friend void f1(); For example, the function f1 is a friend of X<double>, X<string>, and X<Employee>, etc.

Page 54: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates and Friends

• We can also make a friend function of only a class-template specialization with the same type of argument, as in: friend void f2(X<T> &); In this case, if T is a float, function f2(X<float>&) is a friend of class-template specialization X<float>, but not a friend of class-template specialization X<string>.

Page 55: COMS W3101: Programming Languages (C++)areiter/CS_Webpage//COMS3101... · –friend, operator overloading, this pointer •Intro to Inheritance . Outline For Today •Finish up Inheritance

Templates and Friends

• We can also use a member function of another class as a friend of any class-template specialization generated from the class template: friend void A::f3(); This declaration makes member function f3 from (some other) class A a friend of every class-template specialization of this class template. For example, f3 of class A would be a friend of X<double>, X<string>, X<Employee>, etc.