در این جلسه به بررسی الگوها یا 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 نامی جایگزین برای نام نوع داده است، که هنگام نمونهگیری از کلاس تعیین میشود. میتوان بیش از یک نوع داده جنریک را با استفاده از لیست جداشده با کاما تعریف کرد.
در مثال زیر کلاس <>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
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.