Định Nghĩa Chồng Các Hàm (overloading) - VOER

Donate to VNFoundation Project name
  • Trang chủ
  • Tra cứu tài liệu
  • Đóng góp
  • Giới thiệu
    • English
  • Đăng ký
  • Đăng nhập

Đăng nhập

  • Ghi nhớ
  • Quên mật khẩu?
Đăng nhập Bạn chưa có tài khoản? Hãy đăng ký. Tên đăng nhập hoặc mật khẩu chưa đúng TÀI LIỆU Định nghĩa chồng các hàm (overloading) Science and Technology 0

Định nghĩa chồng (hay còn gọi sự tải bội) các hàm là dùng cùng một tên để định nghĩa các hàm khác nhau. Đây là một mở rộng rất có ý nghĩa của C++.

Như đã biết, trong C và các ngôn ngữ khác (như PASCAL, FOXPRO,...) mỗi hàm đều phải có một tên phân biệt. Đôi khi đây là một sự hạn chế lớn, vì phải dùng nhiều hàm khác nhau để thực hiện cùng một công việc. Ví dụ để lấy giá trị tuyệt đối trong C cần dùng tới 3 hàm khác nhau:

int abs(int i); // Lấy giá trị tuyệt đối giá trị kiểu int longt labs(longt l); // Lấy giá trị tuyệt đối giá trị kiểu long double fabs(double d); // Lấy giá trị tuyệt đối giá trị kiểu double

Nhờ khả năng định nghĩa chồng, trong C++ có thể dùng chung một tên cho cả 3 hàm trên như sau:

int abs(int i) ; // Lấy giá trị tuyệt đối giá trị kiểu int longt abs(longt l) ; // Lấy giá trị tuyệt đối giá trị kiểu long double abs(double d) ; // Lấy giá trị tuyệt đối giá trị kiểu double

Khi dùng cùng một tên để định nghĩa nhiều hàm, Trình biên dịch C++ sẽ dựa vào sự khác nhau về tập đối của các hàm này để đổi tên các hàm. Như vậy, sau khi biên dịch mỗi hàm sẽ có một tên khác nhau.

Từ đó cho thấy: các hàm được định nghĩa trùng tên phải có tập đối khác nhau (về số lượng hoặc kiểu). Nếu 2 hàm hoàn toàn trùng tên và trùng đối thì Trình biên dịch sẽ không có cách nào phân biệt được. Ngay cả khi 2 hàm này có kiểu khác nhau thì Trình biên dịch vẫn báo lỗi. Ví dụ sau xây dựng 2 hàm cùng có tên là f và cùng có một đối nguyên a, nhưng kiểu hàm khác nhau. Hàm thứ nhất kiểu nguyên (trả về a*a), hàm thứ hai kiểu void (in giá trị a). Chương trình sẽ bị thông báo lỗi khi biên dịch (bạn hãy thử xem sao)

#include <conio.h> #include <iostream.h> int f(int a); void f(int a); int f(int a) { return a*a; } void f(int a) { cout << "\n " << a ; } void main() { int b=f(5); f(b); getch(); }

Khi gặp một lời gọi, Trình biên dịch sẽ căn cứ vào số lượng và kiểu của các tham số để gọi hàm có đúng tên và đúng bộ đối số tương ứng. Ví dụ:

abs(123); // Tham số kiểu int, gọi hàm int abs(int i) ; abs(123L); // Tham số kiểu long, gọi hàm long abs(long l); abs(3.14); //Tham số kiểu double, gọi hàm double abs(double d);

Khi không có hàm nào có bộ đối cùng kiểu với bộ tham số (trong lời gọi), thì Trình biên dịch sẽ chọn hàm nào có bộ đối gần kiểu nhất (phép chuyển kiểu dễ dàng nhất). Ví dụ:

abs(‘A’) ; // Tham số kiểu char, gọi hàm int abs(int i) ; abs(3.14F); // Tham số kiểu float, gọi hàm double abs(double d);

Như đã nói ở trên, khi xây dựng cũng như sử dụng các hàm trùng tên, Trình biên dịch C++ đã phải suy đoán và giải quyết nhiều trường hợp khá nhập nhằng. Vì vậy không nên lạm dụng quá đáng khả năng định nghĩa chồng, vì điều đó làm cho chương trình khó kiểm soát và dễ dẫn đến sai sót. Việc định nghĩa chồng sẽ hiệu quả hơn nếu được sử dụng theo các lời khuyên sau:

+ Chỉ nên định nghĩa chồng các hàm thực hiện những công việc như nhau nhưng trên các đối tượng có kiểu khác nhau. Ví dụ trong chương trình cần xây dựng các hàm: cộng 2 ma trận vuông kiểu double, cộng 2 ma trận vuông kiểu int, cộng 2 ma trân chữ nhật kiểu double, cộng 2 ma trận chữ nhật kiểu int, thì 4 hàm trên nên định nghĩa chồng (đặt cùng tên).

+ Nên dùng các phép chuyển kiểu (nếu cần) để bộ tham số trong lời gọi hoàn toàn trùng kiểu với bộ đối số của một hàm được định nghĩa chồng. Vì như thế mới tránh được sự nhập nhằng cho Trình biên dịch và Trình biên dịch sẽ chọn đúng hàm cần gọi.

Giả sử có 4 hàm đều có tên là tinh_max được khai báo như sau:

int tinh_max(int a, int b, int c) ; // Max của 3 số nguyên double tinh_max(double a, double b, double c); // Max của 3 số // thực int tinh_max(int *a, int n) ; // Max của một dẫy số nguyên double tinh_max(double *a, int n) ; //Max của một dẫy số thực

Vấn đề đặt ra là làm thế nào lấy được địa chỉ của mỗi hàm. Câu trả lời như sau:

Để lấy địa chỉ của một hàm, ta khai báo một con trỏ hàm có kiểu và bộ đối như hàm cần lấy địa chỉ. Sau đó gán tên hàm cho con trỏ hàm. Ví dụ:

int (*f1)(int , int, int ); f1 = tinh_max ; // Lấy địa chỉ của hàm thứ nhất double (*f2)(double , double, double); f2 = tinh_max ; // Lấy địa chỉ của hàm thứ hai int (*f3)(int *, int ); f3 = tinh_max ; // Lấy địa chỉ của hàm thứ ba double (*f4)(double *, int ); f4 = tinh_max ; // Lấy địa chỉ của hàm thứ tư

Chương trình giải bài toán tìm max của một dẫy số nguyên và max của một dẫy số thực. Trong chươmg trình có 6 hàm. Hai hàm dùng để nhập dẫy số nguyên và dẫy số thực có tên chung là nhapds. Bốn hàm: tính max 2 số nguyên, tính max 2 số thực, tính max của dẫy số nguyên, tính max của dẫy số thực được đặt chung một tên là max.

#include <conio.h>

#include <iostream.h>

#include <iomanip.h>

void nhapds(int *x, int n);

void nhapds(double *x, int n);

int max(int x, int y);

double max(double x, double y);

int max(int *x, int n);

double max(double *x, int n);

void nhapds(int *x, int n)

{

for (int i=1;i<=n;++i)

{

cout << "Phan tu " << i << " = " ;

cin >> x[i] ;

}

}

void nhapds(double *x, int n)

{

for (int i=1;i<=n;++i)

{

cout << "Phan tu " << i << " = " ;

cin >> x[i] ;

}

}

int max(int x, int y)

{

return x>y?x:y ;

}

double max(double x, double y)

{

return x>y?x:y ;

}

int max(int *x, int n)

{

int s=x[1];

for (int i=2;i<=n;++i)

s = max(s,x[i]);

return s;

}

double max(double *x, int n)

{

double s=x[1];

for (int i=2;i<=n;++i)

s = max(s,x[i]);

return s;

}

void main()

{

int a[20] , n , ni, nd, maxi ;

double x[20] , maxd ;

clrscr();

cout << "\nSo phan tu nguyen ni = " ;

cin >> ni ;

cout << "Nhap day so nguyen\n " ;

nhapds(a,ni);

cout << "\nSo phan tu thuc nd = " ;

cin >> nd ;

cout << "Nhap day so thuc\n " ;

nhapds(x,nd);

maxi = max(a,ni);

maxd = max(x,nd);

cout << "\nMax cua day nguyen = " << maxi ;

cout << "\nMax cua day thuc = " << maxd ;

getch();

}

Chương trình sau thực hiện phép nhân ma trận:

D = A*B*C

trong đó A, B là các ma trận vuông, C là ma trận chữ nhật. Trong chương trình có 3 cặp hàm trùng tên để thực hiện 3 nhiệm vụ (nhưng trên 2 đối tượng khác nhau là ma trận vuông và chữ nhật): Nhập ma trận, nhân 2 ma trận và in ma trân.

#include <conio.h>

#include <iostream.h>

#include <iomanip.h>

typedef int MT[20][20];

void nhapmt(MT a,char *ten, int m, int n);

void inmt(MT a,char *ten, int m, int n);

void nhanmt(MT a,MT b, MT c, int m, int n, int p);

void nhapmt(MT a,char *ten, int n);

void inmt(MT a,char *ten, int n);

void nhanmt(MT a,MT b, MT c, int n);

void nhapmt(MT a, char *ten, int m, int n)

{

for (int i=1;i<=m;++i)

for (int j=1;j<=n;++j)

{

cout << "\n" << ten <<"[" << i << "," << j << "]= " ;

cin >> a[i][j];

}

}

void nhapmt(MT a,char *ten, int n)

{

nhapmt(a,ten,n,n) ;

}

void inmt(MT a,char *ten, int m, int n)

{

cout << "\nMa tran: " << ten;

for (int i=1;i<=m;++i)

{

cout << "\n" ;

for (int j=1;j<=n;++j)

cout << setw(6) << a[i][j];

}

}

void inmt(MT a,char *ten, int n)

{

inmt(a,ten,n,n) ;

}

void nhanmt(MT a,MT b, MT c, int m, int n, int p)

{

for (int i=1;i<=m;++i)

for (int j=1;j<=p;++j)

{

c[i][j]=0;

for (int k=1;k<=n;++k)

c[i][j] += a[i][k] * b[k][j];

}

}

void nhanmt(MT a,MT b, MT c, int n)

{

nhanmt(a,b,c,n,n, n) ;

}

void main()

{

MT a,b,c,d; // d= abc

MT u;

clrscr();

nhapmt(a,"A",2);

nhapmt(b,"B",2);

nhapmt(c,"C",2,3);

nhanmt(a,b,u,2);

nhanmt(u,c,d,2,2,3);

inmt(a,"A",2);

inmt(b,"B",2);

inmt(u,"U = A*B",2);

inmt(c,"C",2,3);

inmt(d,"D = U*C",2,3);

getch();

}

0 TẢI VỀ TÁI SỬ DỤNG
  • Tài liệu PDF
  • Tài liệu EPUB
 Nguyễn Thị Hường
  • Phạm Văn Ất
  • 0 GIÁO TRÌNH | 30 TÀI LIỆU
NỘI DUNG CÙNG TÁC GIẢ
  • Các bài toán về ma trận và véc tơ
  • Đối của phương thức, con trỏ this
  • Biến tham chiếu (reference variable)
  • Các phương thức toán tử
  • Hàm, hàm bạn
  • Phạm vi truy xuất
  • Hàm trả về các tham chiếu
  • Truyền giá trị cho hàm theo tham chiếu
  • Định nghĩa chồng các hàm (overloading)
  • Đối có giá trị mặc định
×

VOER message

×

VOER message

Thư viện Học liệu Mở Việt Nam (VOER) được tài trợ bởi Vietnam Foundation và vận hành trên nền tảng Hanoi Spring. Các tài liệu đều tuân thủ giấy phép Creative Commons Attribution 3.0 trừ khi ghi chú rõ ngoại lệ.

  • VOER on Facebook

Từ khóa » Hàm Double Có Nghĩa Là Gì