C++ Primer, Part III: Tools for Class Authors

C++ Primer, Fifth Edition

Stanley B. Lippman
Josée Lajoie
Barbara E. Moo


Chapter 13. Copy Control


13.1 Copy, Assign, and Destroy

13.2 Copy Control and Resource Management

13.3 Swap

13.4 A Copy-Control Example

13.5 Classes That Manage Dynamic Memory

13.6 Moving Objects






Chapter 14. Overloaded Operations and Conversions



14.1 Basic Concepts


14.2 Input and Output Operators

14.3 Arithmetic and Relational Operators

14.4 Assignment Operators

14.5 Subscript Operator

14.6 Increment and Decrement Operators

14.7 Member Access Operators

14.8 Function-Call Operator

14.9 Overloading, Conversions, and Operators


Chapter 15. Object-Oriented Programming



15.1 OOP: An Overview

15.2 Defining Base and Derived Classes

15.3 Virtual Functions

15.4 Abstract Base Classes

15.5 Access Control and Inheritance

15.6 Class Scope under Inheritance

15.7 Constructors and Copy Control

15.8 Containers and Inheritance

15.9 Text Queries Revisited




Chapter 16. Templates and Generic Programming



The distinction between object-oriented programming (OOP) and generic programming is that OOP deals with types that are not known until run time. A template is a blueprint or formula for creating classes or functions. We supply the information needed to transform that blueprint into a specific class or function. That transformation happens during compilation. In this chapter we’ll learn how to define them.

16.1 Defining a Template

16.1.1. Function Templates

A function template is a formula from which we can generate type-specific versions of that function. A template definition :
  • starts with the keyword template
  • followed by a template parameter list
  • It is a comma-separated list of one or more template parameters bracketed by the < and > tokens.
The template version of compare looks like,

template <typename T>
int compare(const T &v1, const T &v2)
{
    if (v1 < v2) return -1;
    if (v2 < v1) return 1;
    return 0;
}
The actual type T represents is determined at compile time based on how compare is used.
To use this function template we use the following format for the function call:

function_name<T> (parameters);
The compiler uses the deduced template parameter(s) to instantiate a specific version of the function for us.
When the compiler instantiates a template, it creates a new “instance” of the template using the actual template argument(s) in place of the corresponding template parameter(s).

// instantiates int compare(const int&, const int&)
cout << compare(1, 0) << endl;       // T is int
// instantiates int compare(const vector<int>&, const vector<int>&)
vector<int> vec1{1, 2, 3}, vec2{4, 5, 6};
cout << compare(vec1, vec2) << endl; // T is vector<int>
the compiler will instantiate two different versions of compare. Each type parameter must be preceded by the keyword class or typename.
The type parameter can be used to name the return type or a function parameter type, and for variable declarations or casts inside the function body:

template <typename T, class U> func(const T&, const U&);
We can define templates that take nontype parameters.
A nontype parameter represents a value rather than a type parameter.
Nontype parameters are specified by using a specific type name instead of the class or typename keyword.
A template nontype parameter is a constant value inside the template definition.

template <unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
    return strcmp(p1, p2);
}

compare("hi", "mom");
A function template can be declared inline or constexpr in the same ways as nontemplate functions.

template <typename T> inline T min(const T&, const T&);
By making the function parameters references to const, we ensure that our function can be used on types whose object cannot be copied.
This design will also make the function run faster.

16.1.2. Class Templates

A class template is a blueprint for generating classes. To use a class template we must supply the list of template arguments inside angle brackets following the template’s name so that the class template can have members that use template parameters as types

template <typename T>
class Array { 
private: 
    T *ptr; 
    int size; 
public: 
    Array(T arr[], int s); 
}; 
  
template <typename T>
Array<T>::Array(T arr[], int s) { 
    ptr = new T[s]; 
    size = s; 
    for(int i = 0; i < size; i++) 
        ptr[i] = arr[i]; 
} 

int arr[5] = {1, 2, 3, 4, 5}; 
Array<int> a(arr, 5); 

A member function of a class template has the same template parameters as the class itself. Therefore, a member function defined outside the class template body starts with the keyword template followed by the class’ template parameter list.
Note, in case that we define a function member outside the declaration of the class template, we must always use class_name<T> to declare the scope of the template function.
But, inside the scope of the class template itself, we may use the name of the template without arguments because we are inside the scope of a class template,.
Each instantiation of a class template constitutes an independent class.

Array<string> names; // Array that holds strings
Array<double> prices;// different element type
Remember that the name of a class template is not the name of a type. A class template is used to instantiate a type, and an instantiated type always includes template argument(s).

16.1.3. Template Parameters

16.2 Template Argument Deduction

16.3 Overloading and Templates

16.4 Variadic Templates

16.5 Template Specializations


留言

熱門文章