Các Tham Số Biểu Thức Trong Khuôn Hình Lớp


khuôn hình lớp một lần rồi sau đó có thể áp dụng chúng với các kiểu dữ liệu khác nhau để được các lớp thể hiện khác nhau.


4.2.2. Tạo một khuôn hình lớp

Xét ví dụ 4.8:

#include<iostream.h>

#include<conio.h> class stack

{

private:

unsigned int max; unsigned int top; int *a;

Có thể bạn quan tâm!

Xem toàn bộ 256 trang tài liệu này.

public:

stack();

Lập trình hướng đối tượng - 20

~stack();

void push(int x); int full();

int empty(); int pop();

};

stack::stack()

{

top=0;

cout<<"Kich thuoc stack:";cin>>max; a = new int[max];

}

stack::~stack()

{

top = 0;

max = 0; delete a;

}

int stack::empty()


{

if(top<=0) return 1;

else return 0;

}

int stack::full()

{

if(top>=max) return 1;

else return 0;

}

void stack::push(int x)

{

if(full())

{

cout<<"stack day"; return;

}

top=top+1; a[top]=x;

}

int stack::pop()

{

if(empty())

{

cout<<"Stack rong"; return 0;

}

top=top-1; return a[top+1];

}

void main()

{

stack s; int n;


cout<<"n=";cin>>n; while(n>0)

{

s.push(n % 2); n = n / 2;

}

while(!s.empty()) cout<<s.pop(); getch();

}

Trên đây là ví dụ về xây dựng lớp stack cài đặt kiểu kề tiếp chứa các phần tử là các số nguyên kiểu int. Lớp stack có một hàm tạo (stack), các phương thức: bổ sung phần tử (push), loại bỏ phần tử (pop), kiểm tra stack đầy (full), kiểm tra stack rỗng (empty). Tuy nhiên, lớp stack trên chỉ làm việc được với các số kiểu int, nếu ta muốn làm việc với các phần tử không phải kiểu int chẳng hạn kiểu float, double, char, hay kiểu student, ...thì ta lại phải xây dựng các lớp khác chỉ với việc thay đổi kiểu dữ liệu cđa thuộc tính a, còn về thuật toán thì không có gì thay đổi. Để tránh sự trùng lặp trong các tình huống như trên, chương trình dịch C++ cho phép định nghĩa một khuôn hình lớp và sau đó áp dụng khuôn hình lớp này với các kiểu dữ liệu khác nhau để thu được các lớp thể hiện như mong muốn.

Cú pháp cđa khuôn hình lớp như sau: template <class T1, class T2, .., class Tn> class tên_lớp

{

//khai báo các thuộc tính có kiểu: T1, T2,.., Tn

//khai báo các phương thức cđa lớp

};

Cũng giống như các khuôn hình hàm, cú pháp template <class T1, class T2,

.., class Tn> xác định rằng đó là một khuôn hình trong đó có các tham số kiểu T1, T2, ..., Tn .

Khi các phương thức được khai bên trong định nghĩa ta sẽ viết như bình thương, còn đối với các phương thức viết ngoài định nghĩa lớp ta phải nhắc lại các tham số kiểu cđa khuôn hình lớp, có nghĩa là phải nhắc lại template <class


T1, class T2, .., class Tn>trước định nghĩa hàm, còn tên cđa khuôn hình lớp được viết như là tên_lớp<T1, T2,.., Tn>

Bây giờ ta sẽ xây dựng khuôn hình lớp stack để có thể làm việc với các kiểu phần tử khác nhau (Trong một stack thì các phần tử có cùng một kiểu dữ liệu)

Ví dụ 4.9:

#include<iostream.h>

#include<conio.h> template <class t> class stack

{

private:

unsigned int max; unsigned int top; t *a;

public:

stack();

~stack();

void push(t x); int full();

int empty(); t pop();

};

template <class t>stack<t>::stack()

{

top=0;

cout<<"Kich thuoc stack:";cin>>max; a = new t[max];

}

template <class t> stack<t>::~stack()

{

top=0; max=0; delete a;


}

template <class t>int stack<t>::empty()

{

if(top<=0) return 1;

else return 0;

}

template <class t>int stack<t>::full()

{

if(top>=max) return 1;

else return 0;

}

template <class t>void stack<t>::push(t x)

{

if(full())

{

cout<<"stack day"; return;

}

top=top+1; a[top]=x;

}

template <class t>t stack<t>::pop()

{

if(empty())

{

cout<<"Stack rong"; return 0;

}

top=top-1; return a[top+1];

}

void main()

{


stack<int> s;//sử dụng khuôn hình lớp stack int n;

cout<<"n=";cin>>n; while(n>0)

{

s.push(n % 2); n = n / 2;

}

while(!s.empty()) cout<<s.pop(); getch();

}


4.2.3. Sử dụng khuôn hình lớp

Sau khi khai báo khuôn hình cđa lớp ta có thể dùng khuôn hình lớp đó để khai báo đối tượng, mảng đối tượng, con trỏ đối tượng bằng cách chỉ rõ kiểu dữ liệu cho các tham số kiểu được sử dụng trong khuôn hình theo cú pháp:

tên_lớp<kiểu dữ liệu1, kiểu dữ liệu 2,.., kiểu dữ liệu n> Tên_đối_tượng;

ng với mỗi kiểu dữ liệu cụ thể cđa một tham số kiểu cho ta một thể hiện cđa khuôn hình lớp. Ví dụ ta có thể có các kiểu thể hiện khác nhau cđa khuôn hình lớp stack khi khai báo các đối tượng như sau:

stack<float> s1; stack<char> s2; stack<*int> s3;


4.2.4. Các tham số trong khuôn hình lớp

Hoàn toàn giống nhkhuôn hình hàm, các khuôn hình lớp có thể có các tham số kiểu vàtham số biểu thức. Tuy có nhiều điểm giống nhau giữa khuôn hình hàm vàkhuôn hình lớp, nhng các ràng buộc đối với các kiểu tham số lại không nhnhau.

Xét ví dụ 4.10:

template <class T, class U, class V> //danh sách ba tham số kiểu class try

{

T x;


U t[5];

...

V fm1 (int, U);

...

};


Để sản sinh ra một lớp thể hiện ta liệt kê đằng sau tên khuôn hình lớp các tham số thực (làtên các kiểu dữ liệu) với số lợng bằng với số các tham số trong danh sách (template<...>) cđa khuôn hình lớp. Ví dụ để sinh ra các lớp thể hiện cđa khuôn hình lớp try ta viết như sau:

try <int, float, int> // lớp thể hiện với ba tham số int, float, int hoặc

try <int,int *, double>// lớp thể hiện với ba tham số int, int *, double hay

try <char *, int, obj> // lớp thể hiện với ba tham số char *, int, obj

Trong dòng cuối ta cuối giả định obj làmột kiểu dữ liệu đã đợc định nghĩa trớc đó. Thậm chí có thể sử dụng các lớp thể hiện để làm tham số thực cho các lớp thể hiện khác, chẳng hạn:

try <float, point<int>, double>

try <point<int>,point<float>, char *>

Ta thấy rằng, vấn đề tơng ứng chính xác đợc nói tới trong các khuôn hình hàm không còn hiệu lực với các khuôn hình lớp. Với các khuôn hình hàm, việc sản sinh một thể hiện không chỉ dựa vào danh sách các tham số có trong template<...> màcòn dựa vào danh sách các tham số hình thức trong tiêu đề cđa hàm. Một tham số hình thức cđa một khuôn hình hàm có thể có kiểu, làmột lớp thể hiện nào đó, chẳng hạn:

template <class T> void fct(point<T>)

{... }

Việc khởi tạo mới các kiểu dữ liệu mới vẫn áp dụng đợc trong các khuôn hình lớp. Một khuôn hình lớp có thể có các thành phần(dữ liệu hoặc hàm) static. Trong

trờng hợp này, cần phải biết rằng, mỗi thể hiện cđa lớp có một tập hợp các thành phần static cđa riêng mình:


4.2.5. Các tham số biểu thức trong khuôn hình lớp

Một khuôn hình lớp có thể chứa các tham số biểu thức. So với khuôn hình hàm, khái niệm tham số biểu thức trong khuôn hình lớp có một số điểm khác biệt: tham số thực tế tơng ứng với tham số biểu thức phải làmột hằng số.

Giả sử rằng ta muốn định nghĩa một lớp array để thao tác trên các mảng một chiều chứa các đối tợng có kiểu bất kỳ. Một cách tự nhiên ta nghĩ ngay đến việc tạo một khuôn hình lớp với một tham số kiểu. Đồng thời còn có thể dùng một tham số thứ hai để xác định số thành phần cđa mảng. Trong trờng hợp này, định nghĩa cđa khuôn hình

lớp có dạng nhsau:

template <class T, int n> class array

{

T tab[n]; public:

...

};

Danh sách các tham số (template<...>) chứa hai tham số với đặc điểm khác nhau hoàn toàn: một tham số kiểu đợc xác đinh bởi từ khoá class, một tham số biểu thức kiểu int>. Chúng ta sẽ phải chỉ rõ giá trị cđa chúng trong khai báo các lớp thể hiện. Chẳng hạn, lớp thể hiện:

array <int ,4>

tơng ứng với khai báo nhsau: class array<int,4>

{

int tab[4]; public:

...

};

Sau đây làmột ví dụ hoàn chỉnh: Ví dụ 4.11:

#include <iostream.h>

#include <conio.h>

template <class T, int n> class array

..... Xem trang tiếp theo?
⇦ Trang trước - Trang tiếp theo ⇨

Ngày đăng: 03/07/2022