User Tools

Site Tools


cpp:class_templates

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 << "--- Printing a ---\n";
  cout << a << endl;
 
  Array<int, 10> b(a);
 
  cout << "--- Printing b ---\n";
  cout << b << endl;
 
  Array<Student,4> sts;
  sts[0] = Student("Kate", 12345);
  sts[1] = Student("Nick", 12346);
  sts[2] = Student("Mary", 12347);
  sts[3] = Student("Susan", 12348);
 
  cout << "--- Printing sts ---\n";
  cout << sts << endl;
 
}
cpp/class_templates.txt · Last modified: 2020/05/25 06:52 (external edit)