C++ Tutorial/template/template class
Содержание
Calculate with SArray
<source lang="cpp">/* 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;
}</source>
class templates
<source lang="cpp">#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;
}</source>
100"
Generic Vector
<source lang="cpp">#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;
}</source>
0 1 4 9 0 1 1.41421 1.73205
template class 2
<source lang="cpp">/* 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";
}</source>
the average value of the integer values is 3 the average value of the characters in "templates" is 108
template class Demo
<source lang="cpp">/* 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";
}</source>
the average value of the integer values is 3 the average value of the characters in "templates" is 108
template counter
<source lang="cpp">/* 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;
}</source>
number of MyString<char>: 2 number of MyString<wchar_t>: 1
template holder class
<source lang="cpp">/* 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();
}</source>