Lập trình hướng đối tượng - Chương 4: Các kỹ thuật xây dựng hàm, sử dụng biến, hằng trong Lập trình hướng đối tượng - Huỳnh Quyết Thắng

Các biến địa phương khai báo cục bộ trong hàm:

– Trong trường hợp các biến địa phương không khai

báo là biến static thì mỗi lần gọi hàm chương trình

dịch lại đăng ký tạo ra biến mới

– Khi chúng ta khai báo các biến địa phương là các biến

static thì chương trình dịch sẽ chỉ khởi tạo duy nhất

một lần (ở lần gọi đầu tiên) biến địa phương này và

thông qua con trỏ stack ở những lần gọi sau chi tham

chiếu tới biến đã tạo ra này để sử dụng lại chúng mà

không tạo ra biến mới

 Tạo một lần/tham chiếu nhiều lần/lưu giá trị của

lần tham chiếu trước

pdf29 trang | Chuyên mục: C/C++ | Chia sẻ: tuando | Lượt xem: 532 | Lượt tải: 0download
Tóm tắt nội dung Lập trình hướng đối tượng - Chương 4: Các kỹ thuật xây dựng hàm, sử dụng biến, hằng trong Lập trình hướng đối tượng - Huỳnh Quyết Thắng, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
) { return ++x; }
 Các hàm được định nghĩa trong thân của một lớp được
tự động trở thành các hàm inline. Tuy nhiên bạn có thể
làm cho một hàm của một lớp trở thành inline mà không
cần định nghĩa nó trong thân lớp bằng cách đặt từ
“inline” vào định nghĩa hàm.
TS H.Q. Thắng - TS C.T. Dũng CNPM 36
Hàm Inline
 Khi bạn tạo một lời gọi tới một hàm inline, 
đầu tiên trình biên dịch phải kiểm tra
chắc chắn rằng lời gọi đó được tạo ra một
cách đúng đắn. Nếu tất cả các thông tin 
về kiểu hàm hợp với ngữ cảnh của lời gọi
thì mã inline sẽ được thay thế trực tiếp
vào chỗ gọi hàm. 
 Từ đó ta thấy rằng một hàm inline phải
được định nghĩa trước khi nó được sử
dụng
19
TS H.Q. Thắng - TS C.T. Dũng CNPM 37
Hàm Inline
 Nếu hàm inline chứa các lệnh điều khiển chương
trình phức tạp ví dụ như các cấu trúc lặp, rẽ
nhánh thì copiler sẽ bỏ qua tính inline của hàm. 
Ta chỉ nên dùng hàm inline để chứa các lệnh
gán, biểu thức và lệnh gọi hàm đơn giản.
 Compiler có thể bỏ qua từ khóa inline nếu như
nó thấy cần thiết. Ví dụ như trong chương trình
của ta có quá nhiều lời gọi tới các hàm inline thì
compiler sẽ bỏ qua tính inline của hàm xì thiếu
bộ nhớ hoặc nếu các hàm inline dài, và các hàm
đệ quy thì không thể là inline.
 So sánh hàm Inline và hàm thường?
TS H.Q. Thắng - TS C.T. Dũng CNPM 38
class CStr
{
char *pData;
int nLength;
public:
//implicit inline function
char *get_Data(void) {return pData; }
int getlength(void);
};
//explicit inline function
inline void CStr::getlength(void) {
return nLength;
}
20
TS H.Q. Thắng - TS C.T. Dũng CNPM 39
Hàm Inline
 Tổng kết về hàm inline:
– Ưu điểm: việc sử dụng hàm inline có tác dụng tiết
kiệm được thời gian không phải thực hiện các xử lý
đầu vào khi gọi hàm như: đẩy đối số vào stack, tạo
một lời gọi, sau đó khi trở về thì phải giải toả các
tham số khỏi stack. Trong nhiều trường hợp mã của
nó nhỏ hơn so với việc nếu nó được cấp phát trên
ngăn xếp.
– Nhược điểm: làm cho chương trình lớn hơn. Việc sử
dụng nhiều lời gọi tới hàm inline và các hàm inline dài
sẽ làm cho chương trình bị phình to.
TS H.Q. Thắng - TS C.T. Dũng CNPM 40
Kỹ thuật chồng hàm trong LTHDT
 Ý tưởng của nguyên lý chồng hàm: cho phép
đặt tên hàm trùng nhau để mô tả bản chất công
việc, nhưng các đối số hoặc kiểu dữ liệu trả về
từ hàm là khác nhau
 Căn cứ vào số lượng hoặc kiểu dữ liệu của các
giá trị truyền cho đối số HĐH sẽ chọn ra hàm
phù hợp nhất để thực hiện trong trường hợp
chồng hàm.
 Nếu như không chọn được hoặc chọn được
>1 (hai hàm trở lên) như vậy thì sẽ báo lỗi.
21
TS H.Q. Thắng - TS C.T. Dũng CNPM 41
Kỹ thuật chồng hàm trong LTHDT
 Phân loại kỹ thuật chồng hàm:
– Chồng hàm dựa trên các đối số: số lượng và
kiểu dữ liệu
– Ví dụ: void f (int); 
void f (int, float); 
void f ();
– Đặc điểm: Chấp nhận ở tất cả các ngôn ngữ
lập trình hướng đối tượng
TS H.Q. Thắng - TS C.T. Dũng CNPM 42
Kỹ thuật chồng hàm trong LTHDT
 Phân loại kỹ thuật chồng hàm:
– Chồng hàm dựa trên kiểu dữ liệu trả về từ
hàm. Ví dụ: 
void f(int);
int f(int);
float f(int);
– Đặc điểm: Khó thực hiện chương trình dich, 
không chấp nhận trong các ngôn ngữ lập
trình hướng đối tượng như C++
22
TS H.Q. Thắng - TS C.T. Dũng CNPM 43
Chồng hàm
 Các điểm cần lưu ý về chồng hàm:
– Các hàm được xem xét là chồng hàm nếu
như chúng phải có cùng phạm vi (cùng
trong một lớp, hoặc một mô-đun)
– Các hàm phải có cùng tên hàm
– Chỉ nên sử dụng khi các hàm có cùng mục
đích, chức năng
 Chồng hàm thường được gặp nhất khi
xây dựng các hàm thiết lập cho lớp
TS H.Q. Thắng - TS C.T. Dũng CNPM 44
Java: định nghĩa chồng phương thức
public class Ship4 {
public double x=0.0, y=0.0, speed=1.0, direction=0.0;
public String name;
public Ship4(double x, double y, double speed, double direction, String name)
{
this.x = x;
this.y = y;
this.speed = speed;
this.direction = direction;
this.name = name;
}
public Ship4(String name) {
this.name = name;
}
private double degreesToRadians(double degrees) {
return(degrees * Math.PI / 180.0);
}
...
23
TS H.Q. Thắng - TS C.T. Dũng CNPM 45
Java: định nghĩa chồng phương thức
public void move() {
move(1);
}
public void move(int steps) {
double angle = degreesToRadians(direction);
x = x + (double)steps * speed * Math.cos(angle);
y = y + (double)steps * speed * Math.sin(angle);
}
public void printLocation() {
System.out.println(name + " is at ("
+ x + "," + y + ").");
}
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 46
Sử dụng phương thức định nghĩa 
chồng
public class Test4 { 
public static void main(String[] args) {
Ship4 s1 = new Ship4("Ship1");
Ship4 s2 = new Ship4(0.0, 0.0, 2.0, 135.0, "Ship2");
s1.move();
s2.move(3);
s1.printLocation();
s2.printLocation();
}
}
24
TS H.Q. Thắng - TS C.T. Dũng CNPM 47
Hàm có đối số mặc định (C++)
 Khai báo hàm void hamf (int x, float y=1.0)
– ý nghĩa: đối số x là đối số không có giá trị mặc định, 
đối số y là đối số có giá trị mặc định
– có thể có hai dạng gọi hàm func:
 func(10); đối số x nhận giá trị x=10 và đối số y nhận giá trị
y=1.0 (giá trị mặc định)
 func(10, 5.0); đối số x nhận giá trị x=10 và đối số y nhận giá
trị y=5.0 (giá trị truyền vào)
 Hàm với các đối số mặc định cho phép they đổi
dạng của hàm khi truyền các giá trị/biến cho các
đối số
TS H.Q. Thắng - TS C.T. Dũng CNPM 48
Hàm có đối số mặc định (C++)
 Nguyên tắc khi khai báo hàm với đối số mặc
định:
– Để đảm bảo chương trình dịch xác định đúng giá
trị/biến truyền cho các đối số chúng ta cần phải giữ
nguyên tắc:
 Các đối số không có giá trị mặc định được xếp lên đầu danh
sách của các đối số của hàm
 Các đối số có giá trị mặc định được xếp xuống cuối danh
sách của các đối số của hàm
 void f (int x, int y, int a=0, float b=1.0)
 Gọi hàm:
 f(1, 2, 5)
(x) (y) (a) (b)1
2
5
25
TS H.Q. Thắng - TS C.T. Dũng CNPM 49
Hàm có đối số mặc định (C++)
int getSum(int, int=0, int=0);// OK
int getSum(int, int=0, int); //wrong!
 Khi một đối số bị bỏ qua trong lời gọi hàm, tất
cả đối số sau nó cũng phải bị bỏ qua.
sum = getSum(num1, num2); // OK
sum = getSum(num1, , num3);// wrong!
Ngôn ngữ Java không hỗ trợ đặc tính này
TS H.Q. Thắng - TS C.T. Dũng CNPM 50
Khi nào sử dụng ?
 Sử dụng hàm với các đối số có giá trị mặc định:
– Thông thường công việc mà hàm đó thực hiện không
thay đổi bản chất hay giải thuật thực hiện. Các đối số
nhận các giá trị mặc định hay truyền vào chỉ làm thay
đổi kết quả mà không thay đổi ý nghĩa công việc.
– Trường hợp thứ hai nên sử dụng hàm có đối số giá trị
mặc định: công việc trong hàm mang tính chất mở
rộng trong những trường hợp đối số nhận những giá
trị truyền vào
26
TS H.Q. Thắng - TS C.T. Dũng CNPM 51
Khi nào sử dụng ?
 Ví dụ (1): void f (int x, int y, int a=0, float b=1.0)
– Công việc thực hiên trong f phụ thuộc vào 4 đối số x, y, a, b 
nhưng thông thường a=0 và b=1 tuy nhiên trong một số trường
hợp a và b có thể nhận những giá trị khác
 Ví dụ (2): void f (int x, int y) 
– bình thường hàm f phụ thuộc vào hai giá trị đối số x,y. Bây giờ
vì lý do phát triển mở rộng f phụ thuộc vào 3 đối số f(int x, int y, 
int a). 
– Làm thế nào có thể định nghĩa lại f mà trong chương trình
những lời gọi cũ khi f có hai đối số không bị ảnh hưởng. Lời giải
khai báo đối số a đối số với giá trị mặc định:
– f (int x, int y, int a=0);
TS H.Q. Thắng - TS C.T. Dũng CNPM 52
Hằng trong LTHDT
 Nguyên lý về hằng trong LTHDT thể hiện các
đặc điểm và tư tưởng lập trình: những gì có thể
thay đổi và những gì không được thay đổi và khi
nào nên sử dụng chúng
 Trong các ngôn ngữ lập trình hướng đối tượng
như có các từ khoá mang ý nghĩa khác nhau để
sử dụng trong những trường hợp khai báo hằng
số:
– const (C++)
– final (java)
27
TS H.Q. Thắng - TS C.T. Dũng CNPM 53
Con trỏ hằng
 Con trỏ tới một hằng:
– const int * pi
– Trong trường hợp này chúng ta khai báo rằng pi là
một con trỏ và giá trị mà pi trỏ tới là một giá trị
không đổi, không được phép sử dụng pi để thay đổi
giá trị này
– int a =10; int b=20; 
– pi=&a; //Lệnh đúng
– pi=&b; //Lệnh đúng
– *pi = 100; //Lệnh sai
TS H.Q. Thắng - TS C.T. Dũng CNPM 54
Hằng con trỏ
 Hằng con trỏ
– int const *pi
– Trong trường hợp này chúng ta khai báo rằng
pi là một con trỏ và là hằng tức là pi trỏ tới
một địa chỉ không đổi, không được phép sử
dụng pi để thay đổi địa chỉ mà pi trỏ tới
– int a =10; int b=20; int const *pi = &a; 
– pi=&b; //Lệnh sai
 *pi = 100; //Lệnh đúng
28
TS H.Q. Thắng - TS C.T. Dũng CNPM 55
Sử dụng hằng trong hàm
 Truyền các đối số bằng từ khoá const
– Khi khai báo hàm sử dụng các từ khóa const để khai
báo các đối số trong hàm, chúng ta dã quy định luôn
là trong thân hàm không thể sử dụng các lện thay đổi
giá trị của các đối số này
void f(const int n)
{ .....
n++; // Lỗi vì đã thay đổi giá trị của n
....
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 56
Giá trị trả về từ hàm là hằng
– Tương tự như trường hợp truyền các đối số, 
chúng ta cũng có thể khai báo hàm có giá trị
trả về là hằng, tức là bên trong thân hàm
không được phép thay đổi biến nằm ở lệnh
return 
– Trên thực tế đối với các dữ liệu cơ bản giá trị
trả về từ hàm không có ý nghĩa
#include 
const int f(int &i) { i++; return (++i); }
void main()
{ int d=1; d=f(d); cout<<d; }
29
TS H.Q. Thắng - TS C.T. Dũng CNPM 57
Hằng trong lớp
 Thành phần dữ liệu là hằng
 Các hàm thành phần có khai báo const sau danh sách 
tham số:
– Không được quyền thay đổi thành phần dữ liệu của đối tượng 
trong lớp. Thường dùng cho các phương thức Get.
– Làm việc trên các hằng đối tượng 
class Class {
public:
Class( int a0, int b0 ) ;
void mf1() const;
void mf2();
private: 
int a, b;
};
void gf1 ( const Class &c ) ;
void gf2 ( Class &c ) ;
void main(void) {
Class c1(1, 2) ;
const Class c2(10, 20) ;
c1.mf1 ( ) ; // OK
c1.mf2 ( ) ; // OK
gf1 ( c1 ) ; // OK
gf2 ( c1 ) ; // OK 
c2.mf1 ( ) ; // OK
c2.mf2 ( ) ; // Syntax error 
gf1 ( c2 ) ; // OK
gf2 ( c2 ) ; // Syntax error 
}

File đính kèm:

  • pdflap_trinh_huong_doi_tuong_chuong_4_cac_ky_thuat_xay_dung_ham.pdf