الگوها یا Templates در ++C

در این جلسه به بررسی الگوها یا Templates در ++C خواهیم پرداخت. الگوها پایه و اساس برنامه‌نویسی جنریک (generic) می‌باشند. در این برنامه‌نویسی، کد به روشی نوشته می‌شود که به هیچ نوع داده  خاصی وابسته نباشد.

یک الگو طرح یا فرمولی برای ساختن یک کلاس یا تابع جنریک است. کانتینرهای (container) کتابخانه مانند شمارشگر (iterator) و الگوریتم (algorithm) مثال‌هایی از برنامه‌نویسی جنریک هستند که با استفاده از مفهوم الگو توسعه یافته‌اند.

هر کانتینر،مانند vector، تنها یک تعریف مشخص دارد، اما می‌توان vectorهایی از انواع مختلف مانند <vector<int یا <vector<string تعریف کرد.

می‌توان از الگوها همچون کلاس‌ها برای تعریف توابع نیز استفاده کرد، اجازه دهید طرز کارآنها را باهم بررسی کنیم.

الگوی تابع (function template)

شکل عمومی ‌تعریف یک الگوی تابع به صورت زیر است.

template <class type> ret-type func-name(parameter list) {
   // body of function
} 

در این تعریف، type یک نام جایگزین برای نوع داده مورد استفاده تابع است. این نام را می‌توان در درون تابع نیز به کار برد.

در مثال زیر الگوی تابعی نوشته شده که از بین دو عدد مقدار بزرگتر را برمی‌گرداند.

#include <iostream>
#include <string>

using namespace std;

template <typename T>
inline T const& Max (T const& a, T const& b) { 
   return a < b ? b:a; 
}

int main () {
   int i = 39;
   int j = 20;
   cout << "Max(i, j): " << Max(i, j) << endl; 

   double f1 = 13.5; 
   double f2 = 20.7; 
   cout << "Max(f1, f2): " << Max(f1, f2) << endl; 

   string s1 = "Hello"; 
   string s2 = "World"; 
   cout << "Max(s1, s2): " << Max(s1, s2) << endl; 

   return 0;
}

اگر کد بالا را اجرا کنید، خروجی زیر حاصل می‌گردد.

Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World

الگوی کلاس

مشابه تعریف یک الگوی تابع، می‌توان الگوی کلاس را نیز تعریف کرد. شکل عمومی‌ کلاس جنریک به صورت زیر است.

template <class type> class class-name {
   .
   .
   .
}

در اینجا، type نامی ‌جایگزین برای نام نوع داده است، که هنگام نمونه‌گیری از کلاس تعیین می‌شود. می‌توان بیش از یک نوع داده جنریک را با استفاده از لیست جداشده با کاما تعریف کرد.

مطلب پیشنهادی:  آموزش کار با CMake

در مثال زیر کلاس <>Stack تعریف شده و متدهای جنریک push و pop در آن پیاده‌سازی شده‌اند.

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;

template <class T>
class Stack { 
   private: 
      vector<T> elems;    // elements 

   public: 
      void push(T const&);  // push element 
      void pop();               // pop element 
      T top() const;            // return top element 
      
      bool empty() const {      // return true if empty.
         return elems.empty(); 
      } 
}; 

template <class T>
void Stack<T>::push (T const& elem) { 
   // append copy of passed element 
   elems.push_back(elem);    
} 

template <class T>
void Stack<T>::pop () { 
   if (elems.empty()) { 
      throw out_of_range("Stack<>::pop(): empty stack"); 
   }
   
   // remove last element 
   elems.pop_back();         
} 

template <class T>
T Stack<T>::top () const { 
   if (elems.empty()) { 
      throw out_of_range("Stack<>::top(): empty stack"); 
   }
   
   // return copy of last element 
   return elems.back();      
} 

int main() { 
   try {
      Stack<int>         intStack;  // stack of ints 
      Stack<string> stringStack;    // stack of strings 

      // manipulate int stack 
      intStack.push(7); 
      cout << intStack.top() <<endl; 

      // manipulate string stack 
      stringStack.push("hello"); 
      cout << stringStack.top() << std::endl; 
      stringStack.pop(); 
      stringStack.pop(); 
   } catch (exception const& ex) { 
      cerr << "Exception: " << ex.what() <<endl; 
      return -1;
   } 
}

اگر کد فوق را اجرا کنیم، نتیجه زیر تولید می‌شود.

7
hello
Exception: Stack<>::pop(): empty stack

منبع: ترجمه از سایت tutorialspoint.com

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

مطالعه دیگر جلسات این آموزش<< جلسه قبلی                    جلسه بعدی >>

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *