TÌM HIỂU CÁCH SỬ DỤNG TỪ KHÓA “CONST” TRONG NGÔN NGỮ LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG C++ – Skin Fresh – 7 ngày sạch mụn – skinfresh.vn

I. Mở đầu

Như ta đã biết, trong những đời sống cũng như trong mọi nghành nghề dịch vụ, luôn có những giá trị không hề biến hóa gọi là hằng số ,

Vd: số π với 100 chữ sô thập phân:

3,1415926535897932384626433832795028841971693993751058209749445923078164 062862089986280348253421170679
Vấn đề là trong tin học, cứ mỗi khi dùng đến giá trị π thì chả lẽ cứ viết hết toàn bộ những chử số ? ? ?

II. Hằng

Nếu dùng một biến để tàng trữ giá trị của hằng số thì có một yếu tố là biến thì đổi khác được giá trị èlỗi .
VD :
float PI = 3,14 ;
/ / / / / /
PI = 8 ;
/ / / / / /

Đoạn mã trên không báo lỗi .
Loại lỗi này rất khó nhận thấy nhưng để lại hậu quả rất to lớn. nếu sau đó ta không quan tâm cứ dùng biến đó trên những đoạn mã cần số π, vậy ta phải dùng hằng để khai báo cho giá trị này .

a. Khai báo hằng trong C++:

Có 2 cách khai báo hằng
– Dùng thông tư # define :
# define A “ gia tri ”
công dụng : định nghĩa macro A đại diện thay mặt cho giá trị dùng để thay thế sửa chữa A trong đoạn mã trừ những đoạn trong “ ” thành giá trị .
thông tư # define còn có nhiều công dụng khác .
– Dùng từ khóa const :
const kiểu tên_hằng = giá_trí ;
kiểu const tên_hằng = giá_trí ;
VD :
const int x = 8 ;
Tác dụng : Khai báo 1 hằng kiểu int tên x có giá trị bằng 8 .
Sau khi khai báo thì ta không hề biến hóa x, ví dụ :
x = 8 ; / / lỗi
Câu lệnh trên báo lỗi vì ta nỗ lực thay đỏi 1 hằng số .

III. Từ khóa const trong C++

Như ta đã biết ở trên, từ khóa const dùng để khai báo hằng :
const kiểu tên_hằng = giá_trí ;
kiểu const tên_hằng = giá_trí ;
VD :
const int x = 8 ;
int const y = 4 ;

Vấn đề ở đây là hai cách khai báo này có khác nhau không ? Và từ khóa const còn công dụng nào không ?
Câu vấn đáp là có .

1. Từ khóa const với con trỏ

Đối với biến con trỏ ta nên phân biệt hai điều : vùng nhớ con trỏ trỏ đến và giá trị của vùng nhớ đó .
Vd :
int x = 10, y = 20 ;
const int * px = và x
Khai báo như vậy, giá trị của vùng nhớ mà px đang trỏ đến là không hề biến hóa được trải qua đổi khác ( * px ). Do đó, ta có những câu lệnh sau :
* px = 15 ; / / lỗi
px = và y
x = 15 ;
Vì ta dùng * px để thay đỏi giá trị của vùng nhớ mà px đang trỏ đến .
Chú ý : Giá trị của x vẫn hoàn toàn có thể được biến hóa, ta chỉ không hề đổi khác giá trị này trải qua px .
Nhưng với những khai báo sau :
int x = 10, y = 20 ;
int * const px = và x
Thì px không hề biến hóa vùng nhớ đang trỏ đến, nhưng giá trị của vùng nhớ hoàn toàn có thể đổi khác trải qua px
* px = y ;
* px = và y / / lỗi
Với khai báo sau :
int x = 10 ;
const int * const px = và x
Bạn không hề đổi khác nơi px đang trỏ đến và trải qua ( * px ) cũng không hề đổi khác giá trị vùng nhớ đó .

2. Từ khóa const với đối tượng

Giả sử ta có lớp với hàm tạo sau :
class A
{
int a ;
public :
A ( int t = 0 ) { a = t ; }
/ / …
} ;
a. Hằng đối tượng người tiêu dùng
Để khai báo hằng đối tượng người dùng ta dùng từ khóa const như sau :
A const a ( 4 ) ;
const A b ;
Ta không hề biến hóa giá trị những thuộc tính của hằng đối tượng người dùng, kể cả trải qua con trỏ trừ khi dùng cách đặc biệt quan trọng .
VD : ta có hàm sau
void A :: set ( int x )
{
a = x ;
}
Thì ta không hề dùng hàm này để đổi khác giá trị của hằng đối tượng người dùng lớp A .
b. Tham chiếu hằng, con trỏ hằng
Giả sử có hàm có đối tượng người dùng nguồn vào sau
type C ( A a )
{
/ / Các câu lệnh
}
Một đối tượng người tiêu dùng object sẽ được tạo và máy sẽ copy hàng loạt giá trị của a vào object rồi giải quyết và xử lý. Vấn đề phát sinh là khi ta có một class với size lớn thì việc chép giá trị vào tham số hình thức ở hàm sẽ làm cho chương trình trở nên chậm đi và đặc biệt quan trọng là sẽ hao phí bộ nhớ và sau khi ra khỏi hàm, bộ nhớ bị hủy khi đó sẽ gọi hàm hủy, rất dễ dẫn đến thực trạng giải phóng lại vùng nhớ đã được giả phóng .
Vì vậy người ta thường dùng tham số chuyền vào là con trỏ hay tham chiếu :
type C ( A * a )
{
/ / Các câu lệnh
}
hoặc
type C ( A và a )
{
/ / Các câu lệnh
}

Hàm trên sử dụng tham số hình thức là một biến con trỏ và hàm dưới dùng một biến tham chiếu. Hai cách khai báo này sẽ cho kết quả tương tự nhau nếu ta không dùng con trỏ để trỏ vào đối tượng khác trong khi dùng hàm. Khi này, với lời gọi hàm như trên thì địa chỉ của x sẽ được truyền vào, do đó sẽ tránh được việc phải chép cả cấu trúc với kích thước lớn.

Nhưng với khai báo như thế thì giá trị của biến truyền vào hoàn toàn có thể bị biến hóa trải qua biến object ( vì là biến con trỏ hoặc tham chiếu ), trong khi với cách khai báo như cũ thì ta không hề muốn giá trị này bị sửa đổi chút nào. Do đó, từ khóa const được sử dụng :
type C ( const A * a )
{
/ / Các câu lệnh
}
type C ( const A và a )
{
/ / Các câu lệnh
}
Lưu ý : 1. dạng khai báo A const và a không còn được khuyến khích .
2. Hàm trả về con trỏ hoàn toàn có thể có dạng
const A * functionName ( / * những đối số * / ) ;
hay
A const * functionName ( / * những đối số * / ) ;
hay
const A const * functionName ( / * những đối số * / ) ;
Khi đó nó được hiểu như trường hợp con trỏ ở trên .
c. Phương thức hằng .
Ở trên ta đã nhắc đến phương pháp hằng, vậy phương pháp hằng là gì ? Tác dụng của nó ?
Như ta đã biêt, một hằng đối tượng người tiêu dùng thì không hề biến hóa những thuộc tính của nó và không được phép gọi những phương pháp hoàn toàn có thể làm biến hóa những thuộc tính của nó, trừ trường hợp đặc biệt quan trọng : những thuộc tính mutable. những phương pháp được những hằng đối tượng người tiêu dùng sử dụng gọi là phương pháp hằng, hay nói cách khác, những hằng đối tượng người tiêu dùng chỉ thao tác trên những phương pháp hằng .
Giả sử với lớp A có một phương pháp print ( ) như sau :
class A
{
int a ;
public :
A ( int t = 0 ) { a = t ; }
/ / …
void print ( ) ;
} ;
void A :: print ( )
{

cout<
}
Ta thấy phương pháp này không hề làm đổi khác những thuộc tính của a, Nhưng nó không hề thao tác được với hằng đối tượng người dùng .
Giả sử ta có 2 câu lệnh sau :
const A a ;
a.print ( ) ; / / / / / / lỗi
Vì sao trình dịch báo lỗi ?
Ta thấy trong hàm print ( ) không hề có lệnh biến hóa thuộc tính ? ? ?
Lí do là trình dịch không hề biết được là ta có đổi khác thuộc tính hay không ở phương pháp không hằng vì một phương pháp không hằng hoàn toàn có thể đổi khác được thuộc tính .
Vậy làm thế nào để hoàn toàn có thể cho hàm trên thực thi được với hằng đối tượng người dùng ?
Ta phải khai báo hàm print ( ) là một phương pháp hằng bằng cách thêm từ khóa const vào sau khai báo của nó trong khai báo lớp như sau :
void print ( ) const ;
Khi đó print ( ) trở thành mọt phương pháp hằng và lớp A Cần được khai báo như sau :
class A
{
int a ;
public :
A ( int t = 0 ) { a = t ; }
/ / …
void print ( ) const ;
} ;
Khi đó 2 câu lệnh này sẽ chạy được :
const A a ;
a.print ( ) ; / / / / / / OK
Nếu ta biến hóa một thuộc tính của đối tượng người dùng thuộc lớp A trải qua phương pháp print ( ) thì sẽ có lỗi .
VD :
void A :: print ( )
{

cout<
a = 7 ; / / / / / / lỗi
}
Vì ta cố gắng nỗ lực đổi khác thuộc tính trải qua phương pháp print ( ) là một phương pháp hằng .
Điều này khá hay trong thiên nhiên và môi trường thao tác cộng tác. Nếu nhiều người cùng kiến thiết xây dựng một lớp : thì cần xác lập cái gì cần biến hóa, biến hóa bằng phương pháp nào ? …
Ở trên có nhắc đến thuộc tính mutable. Vậy thuộc tính này là gì ?
Ta đã biết một phương pháp hằng thì không được đổi khác những thuộc tính của đối tượng người tiêu dùng gọi nó. nhưng đôi lúc cần phải biến hóa những thuộc tính này trải qua phương pháp hằng, kể cả hằng đối tượng người tiêu dùng, khi đó chỉ cần khai báo trước thuộc tính đó từ khóa mutable .
Vậy nếu ta muốn có một phương pháp hằng trả về một con trỏ không hề biến hóa giả trị của vùng nhớ, cũng như vùng nhớ mà con trỏ ấy đang trỏ tới, có tham số nguồn vào là một con trỏ cũng không hề biến hóa giả trị của vùng nhớ, và vùng nhớ mà nó trỏ tới thì ta có một câu lệnh khai báo như sau :
const A const * functionName ( const A const * ) const ; / / 5 từ const ! !

UPDATE
trong C++ giả sử có hàm:

type1 ham ( type và ) ; / / không đổi khác đối số trong thân hàm nha

Khi đó bạn gọi hàm như sau

ham ( 6 ) ; / / / / / / / / loi

Khi đó có lỗi, vì sao?
Vì 6 là 1 hằng.
bạn cần khai báo tường minh hơn.
Và khi đó cần thay đổi hàm này như sau

type1 ham ( const type và ) ; / / / / / / / / /

khi đó lời gọi hàm trên có tác dụng smile

B. KẾT LUẬN:

Từ khóa const trong lập trình nói chung và trong C + + nói riêng, đúng như ý nghĩa của nó trong những nghành nghề dịch vụ khác, là hằng, không đổi .
Tuy nhiên khi dùng từ khóa này ở những thực trạng khác nhau thì ý nghĩa của chúng cũng khác nhau, được cho phép đổi khác một phần hay không cho biến hóa trọn vẹn mà vẫn không đổi khác ý nghĩa đặc trưng của từ khóa này .
Tài liệu tìm hiểu thêm
1. Th.s Nguyễn Xuân Đài – Bài giảng lập hướng đối tượng người dùng
2. GS Phạm Văn Ất – C + + Và Lập trình hướng đối tượng người dùng – NXB KHKT – 1999
3. Thư viện MSDN của Microsoft
4. Website congdongcviet.com
5. Website wikipedia.org
6. Website congdongso.com, với url đơn cử :
http://congdongso.com/threads/2203-C-Const-keyword.html
URL full :
http://forums.congdongcviet.com/showthread.php?t=41764

Đánh giá:

Share this:

Thích bài này:

Thích

Đang tải …