Evaluation Issues in Generic Programming with Inheritance and Templates in C++

Similar documents
What are the characteristics of Object Oriented programming language?

STUDY NOTES UNIT 1 - INTRODUCTION TO OBJECT ORIENTED PROGRAMMING

Instantiation of Template class

AN OVERVIEW OF C++ 1

Cpt S 122 Data Structures. Course Review Midterm Exam # 2

Object Oriented Programming with c++ Question Bank

C++ Important Questions with Answers

Absolute C++ Walter Savitch

Short Notes of CS201

CS201 - Introduction to Programming Glossary By

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

CS304 Object Oriented Programming Final Term

COEN244: Class & function templates

Object Oriented Programming. Solved MCQs - Part 2

Object-Oriented Programming

C++ Coding Standards. 101 Rules, Guidelines, and Best Practices. Herb Sutter Andrei Alexandrescu. Boston. 'Y.'YAddison-Wesley

PROGRAMMING IN C++ COURSE CONTENT

Lecture Notes on Programming Languages

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

VALLIAMMAI ENGINEERING COLLEGE

COMP322 - Introduction to C++

Chapter 5 Object-Oriented Programming

Fast Introduction to Object Oriented Programming and C++

RAJIV GANDHI COLLEGE OF ENGINEERING AND TECHNOLOGY DEPARTMENT OF INFORMATION TECHNOLOGY OBJECT ORIENTED PROGRAMMING QUESTION BANK UNIT I 2 MARKS

Intro to OOP Visibility/protection levels and constructors Friend, convert constructor, destructor Operator overloading a<=b a.

CS304 Object Oriented Programming

OOPS Viva Questions. Object is termed as an instance of a class, and it has its own state, behavior and identity.

Object Oriented Programming in Java. Jaanus Pöial, PhD Tallinn, Estonia

STRUCTURING OF PROGRAM

Cpt S 122 Data Structures. Course Review FINAL. Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University

Dr. Md. Humayun Kabir CSE Department, BUET

Problem Solving with C++

Polymorphism. Contents. Assignment to Derived Class Object. Assignment to Base Class Object

VIRTUAL FUNCTIONS Chapter 10

Object Oriented Paradigm

Assignment 1: grid. Due November 20, 11:59 PM Introduction

Programming, numerics and optimization

ITI Introduction to Computing II

C++ Programming Fundamentals

CS 6456 OBJCET ORIENTED PROGRAMMING IV SEMESTER/EEE

C++ (Non for C Programmer) (BT307) 40 Hours

Advanced C++ Topics. Alexander Warg, 2017

Get Unique study materials from

Interview Questions of C++

The Foundation of C++: The C Subset An Overview of C p. 3 The Origins and History of C p. 4 C Is a Middle-Level Language p. 5 C Is a Structured

ITI Introduction to Computing II

by Pearson Education, Inc. All Rights Reserved. 2

Increases Program Structure which results in greater reliability. Polymorphism

CMSC 202 Section 010x Spring Justin Martineau, Tuesday 11:30am

CHAPTER 1 Introduction to Computers and Programming CHAPTER 2 Introduction to C++ ( Hexadecimal 0xF4 and Octal literals 031) cout Object

Data Abstraction. Hwansoo Han

A Proposal to Add a Const-Propagating Wrapper to the Standard Library

Jayaram college of Engineering and Technology, Pagalavadi. CS2203 Object Oriented Programming Question Bank Prepared By: S.Gopalakrishnan, Lecturer/IT


Preface... (vii) CHAPTER 1 INTRODUCTION TO COMPUTERS

(12-1) OOP: Polymorphism in C++ D & D Chapter 12. Instructor - Andrew S. O Fallon CptS 122 (April 3, 2019) Washington State University

Oops known as object-oriented programming language system is the main feature of C# which further support the major features of oops including:

Software Paradigms (Lesson 3) Object-Oriented Paradigm (2)

Introduction to Programming Using Java (98-388)

Part X. Advanced C ++

I BCS-031 BACHELOR OF COMPUTER APPLICATIONS (BCA) (Revised) Term-End Examination. June, 2015 BCS-031 : PROGRAMMING IN C ++

JAYARAM COLLEGE OF ENGINEERING AND TECHNOLOGY Pagalavadi, Tiruchirappalli (An approved by AICTE and Affiliated to Anna University)

Lecture 13: Object orientation. Object oriented programming. Introduction. Object oriented programming. OO and ADT:s. Introduction

C++ Quick Guide. Advertisements

Object-Oriented Principles and Practice / C++

Week 8: Operator overloading

September 10,

DEPARTMENT OF COMPUTER APPLICATIONS B.C.A. - FIRST YEAR ( REGULATION) SECOND SEMESTER LESSON PLAN SRM INSTITUTE OF SCIENCE AND TECHNOLOGY

Object Oriented Programming in C++ Basics of OOP

Study Guide to Exam 2

CPSC 427a: Object-Oriented Programming

SAURASHTRA UNIVERSITY

Cpt S 122 Data Structures. Templates

Polymorphism. Miri Ben-Nissan (Kopel) Miri Kopel, Bar-Ilan University

Overloading המחלקה למדעי המחשב עזאם מרעי אוניברסיטת בן-גוריון

Note 12/1/ Review of Inheritance Practice: Please write down 10 most important facts you know about inheritance...

INHERITANCE: EXTENDING CLASSES

B.C.A 2017 OBJECT ORIENTED PROGRAMMING USING C++ BCA303T MODULE SPECIFICATION SHEET

Comp 248 Introduction to Programming Chapter 4 & 5 Defining Classes Part B

Concepts of Programming Languages

Exceptions. CandC++ 7. Exceptions Templates. Throwing exceptions. Conveying information

(heavily based on last year s notes (Andrew Moore) with thanks to Alastair R. Beresford. 7. Exceptions Templates 2/1. Throwing exceptions 14 }

Comp 249 Programming Methodology Chapter 8 - Polymorphism

CS304- Object Oriented Programming LATEST SOLVED MCQS FROM FINALTERM PAPERS. MC

Object-oriented Programming. Object-oriented Programming

Subtyping (Dynamic Polymorphism)

CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING C ++ Basics Review part 2 Auto pointer, templates, STL algorithms

Inheritance and Interfaces

PROGRAMMING LANGUAGE 2

G Programming Languages - Fall 2012

Paytm Programming Sample paper: 1) A copy constructor is called. a. when an object is returned by value

Programming Languages: OO Paradigm, Polymorhism and Class Members

Information System Design (IT60105)

CPS 506 Comparative Programming Languages. Programming Language

C++ C and C++ C++ fundamental types. C++ enumeration. To quote Bjarne Stroustrup: 5. Overloading Namespaces Classes

1/29/2011 AUTO POINTER (AUTO_PTR) INTERMEDIATE SOFTWARE DESIGN SPRING delete ptr might not happen memory leak!

Distributed Real-Time Control Systems. Lecture 17 C++ Programming Intro to C++ Objects and Classes

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

Spring 2003 Instructor: Dr. Shahadat Hossain. Administrative Matters Course Information Introduction to Programming Techniques

EL2310 Scientific Programming

Transcription:

Evaluation Issues in Generic Programming with Inheritance and Templates in C++ Emil Vassev, Joey Paquet Department of Computer Science and Software Engineering Concordia University Montreal, Quebec, H3G 1M8, Canada {i_vassev, paquet}@cse.concordia.ca Abstract Generic Programming is a concept and style of programming that increases the correctness and reusability of the source code. In this paper, we draw upon our experience and the experience of other researchers in this field to discuss the advantages and disadvantages of the two major models of generic programming - inheritance and templates. This article reveals some practical cases when the use of the two models is appropriate and when not recommended. Finally, the article concludes with an example of natural coexistence of the two models and demonstrates how they can complement each other. Keywords: Generic Programming, Templates, Inheritance, OOP, Class, Function 1. Introduction Writing generic code is related to making the code reusable and clear, hence it improves the programming efficiency. In C++, there are two major programming models that allow code reuse. Code reuse is possible through inheritance and templates. The main difference lies in how the reuse happens. Whereas in inheritance the code reuse happens across inherited classes, in templates we have a sort of macro substitution of the type name to generate code for that type name. Whereas the main policy provided by inheritance is that the class methods (also called member functions) should be written only once and propagated via inheritance, in programming with templates we follow the principle that algorithms should be written only once and not duplicated across different types [2]. 2. Generic Programming with Inheritance Inheritance is one of the cornerstones of OOP [3]. Inheritance allows classes to inherit class members from other classes. The advantage is that related classes could be clearly expressed, thus avoiding cluttering of programs through reuse of code [4]. By using inheritance, we can arrange classes having common features into a class hierarchy. Class hierarchy specifies a certain order among the similar classes - classes declared lower in the hierarchy inherit features (data and function members) from classes declared higher in the hierarchy. The general idea is to make classes being like another [3] through code reuse. For example, in [5] a star system has the features of a space system, due to the fact the first inherits the last. In addition, a star system maintains a vector of comets and asteroids, those not being maintained by the space system. Hence, the star system is like the space system, which is the base class (also called super class) and the star system is the derived class (also called sub class). Kinds of inheritance. As we have already specified, classes can inherit data and functions. Inheriting functions can be inheritance with

declarations of the function only, or inheritance with declarations and definitions of the functions. We refer to the first case as interface inheritance and the second case as implementation inheritance [1]. In addition, C++ provides three kinds of access inheritance public, protected and private, those restricting in some sense the access to the inherited members. Multiple inheritance is another controversial C++ feature, which allows a class to inherit more than one base class. This could result in complicated inheritance relationships. Ambiguity is one of these complications [6]. For example potential ambiguity is when we have two base classes A and B and both declare a public or protected data member age. Then if C inherits A and B it will have two data members called age, A::age and B::age. Then operation as: C* pc; pc->age; is illegal since it is ambiguous. We resolve the problem by explicit qualification: pc-> A::age. Concepts for generic programming. Generic programming with inheritance relies on two principle concepts: virtual functions and inheritance polymorphism. These two features of inheritance [3] provide a mechanism for providing generic functions that: are defined in the base class in a class hierarchy; will work on all the objects instantiated from derived classes; will have possibly a different behavior for different derived classes. In [1] Grogono defines the virtual functions as an inheritance feature that opens up the possibility of redefinition in derived classes, this leading to polymorphic behaviour. Also in [1] Grogono defines a particular set of circumstances for inheritance polymorphism defined simply as class-dependent behavior. Hence, we draw a conclusion that polymorphism is observed when a derived class object is accessed via a pointer or reference to a base class object and the base class defines a virtual function that is predefined in the derived class. For example in [5] the base class SpaceEntity defines a virtual functions show() that is predefined in all the derived classes. Hence, the polymorphism takes place when we call show() defined in a derived class via a pointer to SpaceEntity class. This technique is also called dynamic binding. In dynamic binding, the determination of which function should be called is not made until run-time [4], as opposed to static binding that happens at compile time [3]. Virtual functions also have the ability to be defined but not declared in a class pure virtual functions. Inheriting a pure virtual function results in interface inheritance (see kinds of inheritance). This introduces a special type of class called abstract class [1]. An abstract class is a class with at least one pure virtual function. Examples for generic programming with inheritance. In [3] Koenig et al. demonstrate how to obtain a value without knowing the object s type. They create a generic inheritance function that compares the grades of two Core objects, where Core is a base class defining the virtual grade() function: bool compare_grades(const Core& c1, const Core& c2) { return c1.grade() < c2.grade(); } This function works for all the instances of Core class as well as for all the instances of Grad class, which class inherits Core class. In the last case, we make polymorphic calls on the grade() function. In [1] Grogono presents an example of generic tree traversal routines one using generic programming with templates and one using generic programming with inheritance. For the inheritance solution to work, the classes must be derived from the same base class and the generic traversal function must have a parameter of type pointer-to-base-class [1]. In contrary, the template solution does not require any dependency between the classes, but the presence of the appropriate functions. Concerning the binding process the difference between the two solutions is that whereas the inheritance solution finds the appropriate derived class at run-time, the template solution matches the template parameters with the appropriate classes at compile time. Hence, each solution has its advantages since the early binding provides high efficiency and late binding

provides high flexibility. In [1] Grogono demonstrates when the inheritance solution is more efficient in case we need more run-time flexibility. Another example for generic programming with inheritance is the following code: Project* getbigger(project* pp1, Project* pp2) { Project *prj; }; if (*pp1 > *pp2) prj = pp1->clone(); else prj = pp2->clone(); return prj; This function compares two projects and creates a project clone of the bigger one. The Project class is the base class in the project hierarchy and the function getbigger() works on any class derived from Project class, since the parameters are pointers to the base class. Operator overloading. The example above reveals another aspect of generic programming operator overloading. In order to make our code generic it is often necessary to overload the standard C++ operators like <, >, ==, <<, >>, +, - etc. Both generic models inheritance and templates rely on operator overloading. Operator overloading is just like function overloading but with some restrictions. An operator function must be a member function or take at least one argument of a class (reference) and cannot have default arguments. Given the overall analysis above and the following examples, we conclude that generic programming with inheritance is appropriate when the generic objects are related through a hierarchical inheritance structure and these objects are open to polymorphic behavior. 3. Generic Programming with Templates Whereas the generic programming with inheritance is object oriented programming, the generic programming with templates is not. In fact, according to Joshua Juran in [2], these two programming models are by no means incompatible. Where does the advantage of using templates lie then? The answer is the nature of templates. Templates establish a style of generic programming that concentrates on the single, typesafe definition of an algorithm that works across any type [2] supporting the operations required by the algorithm. Kinds of templates. C++ provides two kinds of templates: class templates and function templates. Function templates allow writing generic functions that can be used with arbitrary types. For example, we may have searching and sorting routines which can be used with any arbitrary type. The Standard Template Library (STL) generic algorithms have been implemented as function templates, and the containers have been implemented as class templates. Following the rule that templates are not restricted to types, Grogono talks in [1] about non-type parameters template functions. For example, the following template function falls in this category: template<int Max> int randint() { }; and it is called like this: randint<6>(); Here the argument can be only an integer constant. There are some complications coming with the use of templates. In [1] Grogono reveals four possible complications as following: a) Compiling template code. With templates in order to compile, most of the C++ platforms require to put together the declaration and definition code in one header file. This is not a restriction of the concept of templates itself, but rather restriction of the C++ compiler. b) Template return types. There are some restrictions for template functions with return type template parameter. Such functions should have at least one parameter typed with the return type template parameter [1].

template <typename T> T f(const T& param) { }; c) Specialization and function overloading. With template specialization we redefine the default template implementation to handle a particular type in a different way. When we need some special definition for a general template we have a specialized version for this template (class or function), i.e. we specialize the template parameters (some or all of them) with special types. We can specialize class templates partially or fully. For example, the class template template <typename A,typenameB> class X { } can be fully specialized to arrive at: template <> class X<int, int> { } or can be partially specialized to arrive at: template <typename A,typenameB> class X<A, int> { } The function templates can only be fully specialized. The restriction is coming from the fact the function templates are C++ functions and when having the same name they overload. Hence, the function template template< typename A> void f( A, A ); and its partially specialized version template< typename A> void f( A, int ); are in fact two distinct function templates that overload. In [7] Sutter demonstrates some problems when specializing function templates. d) Default arguments. Templates allow default arguments: template <class A = Star, class B=Planet> class SpaceSystem However, definition like the following is not allowed: SpaceSystem s; We must use the brackets < > even though we intend to use the default values: SpaceSystem s < >; Where are the templates appropriate? One of the key strengths of generic programming with templates lies in the paradigm that an algorithm and a user-defined type, each developed without knowledge of the other, can nevertheless be combined [2]. The use of templates reduces the redundancy in the source code but does not affect the functionality of the code. In C++ without templates, in order to make our functions generic, we generate overloaded versions for the various data types. For example we will have multiple versions of the max(x,y) function, which function returns the larger of x and y. However, using templates provides much simpler way to do this. With templates, we define only one version of our function, i.e. we define the algorithm. The use of function templates is not appropriate in case we expect the compiler to convert the function arguments implicitly for us. The generic template functions prevent implicit conversions in some cases. In [1] Grogono demonstrates the problem arising with the max() function when the last is called as following: max (1, 3.4) This call is not possible because the compiler does not convert argument 1 from integer to double. In order to solve the problem we can explicitly cast one of the arguments: max (static_cast<double>(1), 3.4) Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues etc, which constructs can be used with any arbitrary type. For example, we can easily implement a generic template class Queue<T> that stores any type of objects, integral types or even pointers. One

of the most famous STL template class is the vector class. In [5] the base class SpaceSystem maintains two sets one of gravity objects and one of satellites. Those sets are implemented as vectors of pointer objects: std::vector<a*> gravityobjects; std::vector<b*> satellites; Generally, the use of class templates is always appropriate when we want our class to be independent on the type of object it is intended to manage. In [3] Koenig and Moo demonstrate a generic template class called handle that encapsulates a handle behavior, i.e. it refers to an object and when we destroy the handle object it will destroy the associated object as well. The use of templates requires knowledge about the nature of the template arguments. It is extremely important to ensure that template arguments incorporate the behavior required by the template algorithm. For example, a class passed as a template parameter defines a function doit() if such function is called within the template body: template<class T> void executetask(t task) { task.doit(); }; C++ templates are a powerful tool for creating reusable code and they become even more powerful by relying on predefined library like the STL and Boost [1]. The STL provides containers, iterators, and algorithms. Boost includes libraries for threading and smart pointers. Smart pointers are reference counting pointer objects useful for deallocating memory. 4. Conclusion Generic programming with inheritance and generic programming with templates provide different approaches in making our code generic. A better approach or maybe better generic programming model will be the coexistence of these two models. For the development of Universum [5], we apply both generic programming models in an attempt to achieve a level of generic programming that is not possible if you stick only with one of them. The result is a coexistence of templates and inheritance where each working in its most appropriate area. We used templates for object containers and for the base SpaceSystem class. The SpaceSystem class is an abstract template class. It defines all the common functionality for all the possible space systems star system, planet system, galaxy and universe. By providing different template arguments, we specify different set of data and common functionality for each one, those preventing from redundancy coming with the creation of multiple base classes. By providing different definitions for the virtual member functions in the derived classes, we provide a polymorphic behavior for those functions. Therefore, we demonstrated the two generic programming models together in action, complementing each other for the common goal improving the generic programming. References [1] P. Grogono, Software Development with C++, Lecture Notes, Concordia University, Quebec, Canada, 2005 [2] J. Juran, L.F. Bic et al. Using Generic Programming Techniques in C++ with the Mac OS Toolbox, The Advanced Developers Hands on Conference, 2002, http://www.adhocconference.com/papers/2002/generic_p rogramming.pdf [3] A. Koenig, B. E. Moo, Accelerated C++, Pearson Education Inc., Boston, 2000 [4] Fr. Coenen, Inheritance, Lecture Notes, University of Liverpool, http://www.csc.liv.ac.uk/~frans/oldlectures/2cs45/oop/o op3.html [5] E. Vassev, Universum, COMP 6441 Term Project, Concordia University, Quebec, Canada, fall 2005 [6] Bjarne Stroustrup, Multiple Inheritance for C++, AT&T Bell Laboratories, Murray Hill, New Jersey, http://www-plan.cs.colorado.edu/diwan/class-papers/mi.pdf [7] Herb Sutter, Why Not Specialize Function Templates?, C/C++ Users Journal, 19(7), July 2001