C++ Tutorial/template/template class

Материал из C\C++ эксперт
Перейти к: навигация, поиск

Calculate with SArray

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */

#include <stddef.h>
#include <cassert>
template<typename T>
class SArray {
  public:
    // create array with initial size
    explicit SArray (size_t s)
     : storage(new T[s]), storage_size(s) {
        init();
    }
    // copy constructor
    SArray (SArray<T> const& orig)
     : storage(new T[orig.size()]), storage_size(orig.size()) {
        copy(orig);
    }
    // destructor: free memory
    ~SArray() {
        delete[] storage;
    }
    // assignment operator
    SArray<T>& operator= (SArray<T> const& orig) {
        if (&orig!=this) {
            copy(orig);
        }
        return *this;
    }
    // return size
    size_t size() const {
        return storage_size;
    }
    // index operator for constants and variables
    T operator[] (size_t idx) const {
        return storage[idx];
    }
    T& operator[] (size_t idx) {
        return storage[idx];
    }
  protected:
    // init values with default constructor
    void init() {
        for (size_t idx = 0; idx<size(); ++idx) {
            storage[idx] = T();
        }
    }
    // copy values of another array
    void copy (SArray<T> const& orig) {
        assert(size()==orig.size());
        for (size_t idx = 0; idx<size(); ++idx) {
            storage[idx] = orig.storage[idx];
        }
    }
  private:
    T*     storage;       // storage of the elements
    size_t storage_size;  // number of elements
  public:
    SArray<T>& operator+= (SArray<T> const& b);
    SArray<T>& operator*= (SArray<T> const& b);
    SArray<T>& operator*= (T const& s);
};

// addition of two SArrays
template<typename T>
SArray<T> operator+ (SArray<T> const& a, SArray<T> const& b)
{
    SArray<T> result(a.size());
    for (size_t k = 0; k<a.size(); ++k) {
        result[k] = a[k]+b[k];
    }
    return result;
}
// multiplication of two SArrays
template<typename T>
SArray<T> operator* (SArray<T> const& a, SArray<T> const& b)
{
    SArray<T> result(a.size());
    for (size_t k = 0; k<a.size(); ++k) {
        result[k] = a[k]*b[k];
    }
    return result;
}
// multiplication of scalar and SArray
template<typename T>
SArray<T> operator* (T const& s, SArray<T> const& a)
{
    SArray<T> result(a.size());
    for (size_t k = 0; k<a.size(); ++k) {
        result[k] = s*a[k];
    }
    return result;
}
// multiplication of SArray and scalar
// addition of scalar and SArray
// addition of SArray and scalar
//...

// additive assignment of SArray
template<class T>
SArray<T>& SArray<T>::operator+= (SArray<T> const& b)
{
    for (size_t k = 0; k<size(); ++k) {
        (*this)[k] += b[k];
    }
    return *this;
}
// multiplicative assignment of SArray
template<class T>
SArray<T>& SArray<T>::operator*= (SArray<T> const& b)
{
    for (size_t k = 0; k<size(); ++k) {
        (*this)[k] *= b[k];
    }
    return *this;
}
// multiplicative assignment of scalar
template<class T>
SArray<T>& SArray<T>::operator*= (T const& s)
{
    for (size_t k = 0; k<size(); ++k) {
        (*this)[k] *= s;
    }
    return *this;
}

int main()
{
    SArray<double> x(1000), y(1000);
    //...
    // process x = 1.2*x + x*y
    SArray<double> tmp(x);
    tmp *= y;
    x *= 1.2;
    x += tmp;
}

class templates

#include <iostream.h>
template <class T>
class MyClass {
    T value1, value2;
  public:
    MyClass (T first, T second){
        value1=first; 
        value2=second;
    }
    T getmax ()
    {
      T retval;
      retval = value1>value2 ? value1 : value2;
      return retval;
    }
    
};
int main () {
  MyClass <int> myobject (100, 75);
  
  cout << myobject.getmax();
  
  return 0;
}
100"

Generic Vector

#include <iostream.h>
#include <math.h>
template <class T>
class Vector
{
  T * pData;
  int nSize;
  public:
    Vector(int);
    ~Vector() {delete [] pData;}
    T& operator [] (int i) {return pData[i];}
};
template <class T>
Vector <T>::Vector(int n)
{
       pData = new T[n];
    nSize = n;
};
main()
{
    Vector <int> iV(4);
    int i;
    for ( i = 0;i < 4;i++)
       iV[i] = i*i;
    for ( i = 0;i < 4;i++)
          cout << iV[i] << "  ";
    cout << endl;
    Vector <double> dV(4);
    for ( i = 0; i < 4;i++)
      dV[i] = sqrt(i);
    for ( i = 0;i < 4;i++)
         cout << dV[i] << "  ";
    cout << endl;
       return 0;
}
0  1  4  9
0  1  1.41421  1.73205

template class 2

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>

template<typename T>
class AccumulationTraits;
template<>
class AccumulationTraits<char> {
  public:
    typedef int AccT;
    static AccT const zero = 0;
};
template<>
class AccumulationTraits<short> {
  public:
    typedef int AccT;
    static AccT const zero = 0;
};
template<>
class AccumulationTraits<int> {
  public:
    typedef long AccT;
    static AccT const zero = 0;
};

template <typename T>
inline
typename AccumulationTraits<T>::AccT accum (T const* beg,
                                            T const* end)
{
    // return type is traits of the element type
    typedef typename AccumulationTraits<T>::AccT AccT;
    AccT total = AccumulationTraits<T>::zero;
    while (beg != end) {
        total += *beg;
        ++beg;
    }
    return total;
}

int main()
{
    // create array of 5 integer values
    int num[] = { 1, 2, 3, 4, 5 };
    // print average value
    std::cout << "the average value of the integer values is "
              << accum(&num[0], &num[5]) / 5
              << "\n";
    // create array of character values
    char name[] = "templates";
    int length = sizeof(name)-1;
    // (try to) print average character value
    std::cout << "the average value of the characters in \""
              << name << "\" is "
              << accum(&name[0], &name[length]) / length
              << "\n";
}
the average value of the integer values is 3
the average value of the characters in "templates" is 108

template class Demo

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>

template<typename T>
class AccumulationTraits;
template<>
class AccumulationTraits<char> {
  public:
    typedef int AccT;
};
template<>
class AccumulationTraits<short> {
  public:
    typedef int AccT;
};
template<>
class AccumulationTraits<int> {
  public:
    typedef long AccT;
};
template<>
class AccumulationTraits<unsigned int> {
  public:
    typedef unsigned long AccT;
};
template<>
class AccumulationTraits<float> {
  public:
    typedef double AccT;
};

template <typename T>
inline
typename AccumulationTraits<T>::AccT accum (T const* beg,
                                            T const* end)
{
    // return type is traits of the element type
    typedef typename AccumulationTraits<T>::AccT AccT;
    AccT total = AccT();  // assume AccT() actually creates a zero value
    while (beg != end) {
        total += *beg;
        ++beg;
    }
    return total;
}
int main()
{
    // create array of 5 integer values
    int num[] = { 1, 2, 3, 4, 5 };
    // print average value
    std::cout << "the average value of the integer values is "
              << accum(&num[0], &num[5]) / 5
              << "\n";
    // create array of character values
    char name[] = "templates";
    int length = sizeof(name)-1;
    // (try to) print average character value
    std::cout << "the average value of the characters in \""
              << name << "\" is "
              << accum(&name[0], &name[length]) / length
              << "\n";
}
the average value of the integer values is 3
the average value of the characters in "templates" is 108

template counter

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <stddef.h>
template <typename CountedType>
class ObjectCounter {
  private:
    static size_t count;    // number of existing objects
  protected:
    // default constructor
    ObjectCounter() {
        ++count;
    }
    // copy constructor
    ObjectCounter (ObjectCounter<CountedType> const&) {
        ++count;
    }
    // destructor
    ~ObjectCounter() {
        --count;
    }
  public:
    // return number of existing objects:
    static size_t live() {
        return count;
    }
};
// initialize counter with zero
template <typename CountedType>
size_t ObjectCounter<CountedType>::count = 0;

template <typename CharT>
class MyString : public ObjectCounter<MyString<CharT> > {
  //...
};
int main()
{
    MyString<char> s1, s2;
    MyString<wchar_t> ws;
    std::cout << "number of MyString<char>:    "
              << MyString<char>::live() << std::endl;
    std::cout << "number of MyString<wchar_t>: "
              << ws.live() << std::endl;
}
number of MyString<char>:    2
number of MyString<wchar_t>: 1

template holder class

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
template <typename T>
class Holder {
  private:
    T* ptr;    // refers to the object it holds (if any)
  public:
    // default constructor: let the holder refer to nothing
    Holder() : ptr(0) {
    }
    // constructor for a pointer: let the holder refer to where the pointer refers
    explicit Holder (T* p) : ptr(p) {
    }
    // destructor: releases the object to which it refers (if any)
    ~Holder() {
        delete ptr;
    }
    // assignment of new pointer
    Holder<T>& operator= (T* p) {
        delete ptr;
        ptr = p;
        return *this;
    }
    // pointer operators
    T& operator* () const {
        return *ptr;
    }
    T* operator-> () const {
        return ptr;
    }
    // get referenced object (if any)
    T* get() const {
        return ptr;
    }
    // release ownership of referenced object
    void release() {
        ptr = 0;
    }
    // exchange ownership with other holder
    void exchange_with (Holder<T>& h) {
        swap(ptr,h.ptr);
    }
    // exchange ownership with other pointer
    void exchange_with (T*& p) {
        swap(ptr,p);
    }
  private:
    // no copying and copy assignment allowed
    Holder (Holder<T> const&);
    Holder<T>& operator= (Holder<T> const&);
};

class Something {
  public:
    void perform() const {
    }
};
void do_two_things()
{
    Holder<Something> first(new Something);
    first->perform();
    Holder<Something> second(new Something);
    second->perform();
}
int main()
{
    do_two_things();
}