This is an old revision of the document!
Table of Contents
Templates κλάσεων
Σε αναλογία με τα templates συναρτήσεων μπορούμε να κατασκευάσουμε κλάσεις που να λαμβάνουν ως παράμετρο ένα ή περισσότερους τύπους δεδομένων. Στο παρακάτω παράδειγμα, έχουμε την κλάση Box<T> η οποία είναι παραμετρική.
- Box.hpp
#ifndef _BOX_HPP_ #define _BOX_HPP_ template <typename T> class Box { T e; public: Box(T e); T get() const; void set(T e); template <typename U> friend std::ostream& operator<<(std::ostream& out, const Box<U>& t); }; template <typename T> Box<T>::Box(T e) { this->e = e; } template <typename T> T Box<T>::get() const { return e; } template <typename T> void Box<T>::set(T e) { this->e = e; } template <typename T> std::ostream& operator<<(std::ostream& out, const Box<T>& t) { out << t.get(); return out; } #endif
H παραπάνω κλάση μπορεί να παράγει διαφορετικούς τύπους δεδομένων, ανάλογα με τον τύπο T. Στο παρακάτω παράδειγμα έχουμε ένα μία κλάση Box<int>, μία κλάση Box<double> και μία κλάση Box<Student>.
- BoxUsage.cpp
#include <iostream> #include "Box.hpp" #include "Student.hpp" using namespace std; int main() { Box<int> b(15); Box<double> d(4.23); Student kate = {"Kate", 1234}; Box<Student> studentBox(kate); Student katherine = studentBox.get(); katherine.setName("Katherine"); cout << "--- Printing Values ---" << endl; cout << kate << endl; cout << katherine << endl; cout << studentBox.get() << endl; cout << "--- Destroying objects ---" << endl; }
Ένα πιο σύνθετο παράδειγμα
Ας υποθέσουμε ότι θέλουμε να κατασκευάσουμε ένα στατικό πίνακα (συγκεκριμένης χωρητικότητας) για την αποθήκευση πληροφορίας. Σε αναλογία με την κλάση Box<Τ> θέλουμε να φτιάξουμε ένα πίνακα στον οποίο να μπορούμε να αποθηκεύσουμε διαφορετικούς τύπους δεδομένων. Η παρακάτω κλάση Array<T> περιέχει ένα στατικό πίνακα δεδομένων μεγέθους size:
- Array.hpp
#ifndef __ARRAY_H__ #define __ARRAY_H__ #include <iostream> #include <cstring> #include <cassert> template <typename T, int size> class Array { T array[size]; public: Array(); Array(const Array<T,size>& a); void set(T e, int index); T get(int index) const; void rmv(int index); Array<T,size>& operator=(Array<T,size>& a); T& operator[](int index); template<typename U, int k> friend std::ostream &operator<<(std::ostream& out, const Array<U,k>& t); }; template<typename T, int size> Array<T,size>::Array() { // empty } template<typename T, int size> Array<T,size>::Array(const Array<T,size>& a) { for(int i=0; i<size; i++) array[i] = a.array[i]; } template<typename T, int size> void Array<T,size>::set(T e, int index) { assert(index>=0 && index<size); array[index] = e; } template<typename T, int size> T Array<T,size>::get(int index) const { assert(index>=0 && index<size); return array[index]; } template<typename T, int size> void Array<T,size>::rmv(int index) { assert(index>=0 && index<size); for(int i=index+1; i<size; i++) array[i-1] = array[i]; } template<typename T, int size> Array<T,size>& Array<T,size>::operator=(Array<T,size>& a) { for(int i=0; i<size; i++) array[i] = a.array[i]; } template<typename T, int size> T& Array<T,size>::operator[](int index) { assert(index>=0 && index<size); return array[index]; } template<typename T, int size> std::ostream &operator<<(std::ostream& out, const Array<T,size>& t) { for(int i=0; i<size; i++) { out << t.array[i] ; if(i<size-1) out << ", "; } return out; } #endif
- ArrayUsage.cpp
#include "Array.hpp" #include "Student.hpp" #define ARRAY_SIZE 10 using namespace std; int main() { Array<int, ARRAY_SIZE> a; for(int i=0; i<ARRAY_SIZE; i++) a[i] = i; cout << a << endl; Array<int, ARRAY_SIZE> b(a); cout << b << endl; Array<Student, ARRAY_SIZE> sts; sts[0] = Student("Kate", 12345); sts[1] = Student("Nick", 12346); sts[2] = Student("Mary", 12347); cout << sts << endl; }