<< Chapter < Page Chapter >> Page >

double fabs(double d);

Tất cả các hàm này đều cùng thực hiện một chứa năng nên chúng ta thấy điều này nghịch lý khi phải có ba tên khác nhau. C++ giải quyết điều này bằng cách cho phép chúng ta tạo ra các hàm khác nhau có cùng một tên. Đây chính là đa năng hóa hàm. Do đó trong C++ chúng ta có thể định nghĩa lại các hàm trả về trị tuyệt đối để thay thế các hàm trên như sau :

int abs(int i);

long abs(long l);

double abs(double d);

Ví dụ 2.16:

1: #include<iostream.h>

2: #include<math.h>

3:

4: int MyAbs(int X);

5: long MyAbs(long X);

6: double MyAbs(double X);

7:

8: int main()

9: {

10:    int X = -7;

11:    long Y = 200000l;

12:    double Z = -35.678;

13:    cout<<"Tri tuyet doi cua so nguyen (int) "<<X<<" la "

14:       <<MyAbs(X)<<endl;

15:    cout<<"Tri tuyet doi cua so nguyen (long int) "<<Y<<" la "

16:       <<MyAbs(Y)<<endl;

17:    cout<<"Tri tuyet doi cua so thuc "<<Z<<" la "

18:       <<MyAbs(Z)<<endl;

19:    return 0;

20: }

21:

22: int MyAbs(int X)

23: {

24:    return abs(X);

25: }

26:

27: long MyAbs(long X)

28: {

29:    return labs(X);

30: }

31:

32: double MyAbs(double X)

33: {

34:    return fabs(X);

35: }

Chúng ta chạy ví dụ 2.16 , kết quả ở hình 2.19

Hình 2.19: Kết quả của ví dụ 2.16

Trình biên dịch dựa vào sự khác nhau về số các tham số, kiểu của các tham số để có thể xác định chính xác phiên bản cài đặt nào của hàm MyAbs() thích hợp với một lệnh gọi hàm được cho, chẳng hạn như:

MyAbs(-7); //Gọi hàm int MyAbs(int)

MyAbs(-7l); //Gọi hàm long MyAbs(long)

MyAbs(-7.5); //Gọi hàm double MyAbs(double)

Quá trình tìm được hàm được đa năng hóa cũng là quá trình được dùng để giải quyết các trường hợp nhập nhằng của C++. Chẳng hạn như nếu tìm thấy một phiên bản định nghĩa nào đó của một hàm được đa năng hóa mà có kiểu dữ liệu các tham số của nó trùng với kiểu các tham số đã gởi tới trong lệnh gọi hàm thì phiên bản hàm đó sẽ được gọi. Nếu không trình biên dịch C++ sẽ gọi đến phiên bản nào cho phép chuyển kiểu dễ dàng nhất.

MyAbs(‘c’); //Gọi int MyAbs(int)

MyAbs(2.34f); //Gọi double MyAbs(double)

Các phép chuyển kiểu có sẵn sẽ được ưu tiên hơn các phép chuyển kiểu mà chúng ta tạo ra (chúng ta sẽ xem xét các phép chuyển kiểu tự tạo ở chương 3).

Chúng ta cũng có thể lấy địa chỉ của một hàm đã được đa năng hóa sao cho bằng một cách nào đó chúng ta có thể làm cho trình biên dịch C++ biết được chúng ta cần lấy địa chỉ của phiên bản hàm nào có trong định nghĩa. Chẳng hạn như:

int (*pf1)(int);

long (*pf2)(long);

int (*pf3)(double);

pf1 = MyAbs; //Trỏ đến hàm int MyAbs(int)

pf2 = MyAbs; //Trỏ đến hàm long MyAbs(long)

pf3 = MyAbs; //Lỗi!!! (không có phiên bản hàm nào để đối sánh)

Các giới hạn của việc đa năng hóa các hàm:

Bất kỳ hai hàm nào trong tập các hàm đã đa năng phải có các tham số khác nhau.

Các hàm đa năng hóa với danh sách các tham số cùng kiểu chỉ dựa trên kiểu trả về của hàm thì trình biên dịch báo lỗi. Chẳng hạn như, các khai báo sau là không hợp lệ:

void Print(int X);

int Print(int X);

Không có cách nào để trình biên dịch nhận biết phiên bản nào được gọi nếu giá trị trả về bị bỏ qua. Như vậy các phiên bản trong việc đa năng hóa phải có sự khác nhau ít nhất về kiểu hoặc số tham số mà chúng nhận được.

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Co nuoi. OpenStax CNX. Jul 29, 2009 Download for free at http://cnx.org/content/col10760/1.1
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Co nuoi' conversation and receive update notifications?

Ask