2015年7月1日 星期三

Template與繼承的組合



C++ 中的 Template 大致有三種用法,Function Template、Specialization,和 Class Template。

Function Template 就是保留函式的參數型態,或函式內的變數型態,等到執行時再依主程式傳入的參數來決定,以提高函式的泛用性,例如


#include <iostream>


template <typename T>

void swap(T& a,T& b) {
   T tmp=a;
   a=b;
   b=tmp;
}

template <typename T1, typename T2>

T1 max(T1 x, T2 y)
{
  return (x>y) ? x : y;
}

int main() {

   float x=3.14, y=98.9;
   swap(x,y);
   std::cout << x << " " << y << " " << max(x,99);
   int a=1, b=2;
   swap(a,b);
   std::cout << a << " " << b << " " << max(a,b);
   return 0;
}

上面第一個 swap 函式僅以主程式傳來的一種參數型態運作,所以 a b 參數的型態必須相同,否則會產生編譯錯誤。第二個 max 函式則接受兩種參數型態,T1 與 T2 型態可以相同或不同(不考慮是否影響程式運算),並以T1參數型態之值回傳。template <typename T>的寫法可改為 template <class T>,兩者功能一樣。

Specialization 特化,就是例外處理,由於 Function Template 讓函式產生泛用性,但若有需要對特定的資料型別進行其他處理,則可宣告一個同名 Template 函式並指定參數型別,來撰寫例外處理程式


#include <iostream>

template <typename T>  //樣板函式1

void swap(T& a,T& b) {
   T tmp=a;
   a=b;
   b=tmp;
}

template <> //樣板函式2

void swap<int>(int& a,int& b) {
a=b=0;
}

int main() {

   float a=50, b=100;
   swap(a,b); //float 叫用樣板函式1
   std::cout << a << " " << b << std::endl;
   int x=50, y=100;   
   swap(x,y); //Specialization, int 叫用樣板函式2 
   std::cout << x << " " << y << std::endl;
   return 0;

}

第三種 Class Template 在 "Class template 類別樣版/模板" 這篇已有介紹,以下針對一般 Class 和 Class Template 之間繼承情況做一整理。


按照一般 class 與 class template 分別為父類別、衍生類別的排列組合有四

父類別衍生類別
classclass
classtemplate
templateclass
templatetemplate

以上四種組合在 C++ 中都是允許的,以下程式即示範各種繼承關係

#include <iostream>

class baseClass1 {
public:
    int a;
};

template <typename T> class baseClass2 {
public:
    T b;
};

class sonClass1 : public baseClass1 {
public:
int c;
};

class sonClass2 : public baseClass2<float> {
public:
int d;
};

template <typename T> class sonClass3 : public baseClass1 {
public:
T e;
};

template <typename T> class sonClass4 : public baseClass2<int> {
public:
T f;
};

template <typename T> class sonClass5 : public baseClass2<T> {
public:
T g;
};

int main()
{
baseClass1 b1;
baseClass2<float> b2;
sonClass1 s1;
sonClass2 s2;
sonClass3<float> s3;
sonClass4<float> s4;
sonClass5<float> s5;

b1.a=1; //int

b2.b=3.14; //T

s1.a=1; //int
s1.c=1; //int

s2.b=3.14; //T
s2.d=1; //int

s3.a=1; //int
s3.e=3.14; //T

s4.b=3.14; //T int
s4.f=3.14; //T

s5.b=3.14; //T
s5.g=3.14; //T

std::cout << b1.a << std::endl;
std::cout << b2.b << std::endl;
std::cout << s1.a << std::endl;
std::cout << s1.c << std::endl;
std::cout << s2.b << std::endl;
std::cout << s2.d << std::endl;
std::cout << s3.a << std::endl;
std::cout << s3.e << std::endl;
std::cout << s4.b << std::endl;
std::cout << s4.f << std::endl;
std::cout << s5.b << std::endl;
std::cout << s5.g << std::endl;

    return 0;

}

沒有留言:

張貼留言