Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 19 kết quả

Đề tài: Cách sử dụng từ khóa const trong C++

  1. #1
    Ngày gia nhập
    03 2009
    Nơi ở
    Ở địa ngục
    Bài viết
    667

    Mặc định Cách sử dụng từ khóa const trong C++

    Làm tiểu luận về cái này, có lẽ cũng nên post lên cái.

    Có lẽ nhiều người chưa biết hết tác dụng của từ khoá này.

    A. NỘI DUNG:
    I. Mở đầu
    Như ta đã biết, trong các đời sống cũng như trong mọi lĩnh vực, luôn có các giá trị không thể thay đổi gọi là hằng số,
    Vd: số π với 100 chữ sô thập phân:
    3,141592653589793238462643383279502884197169399375 10582097494459230781640628620899862803482534211706 79
    Vấn đề là trong tin học, cứ mỗi khi dùng đến giá trị π thì chả lẽ cứ viết hết tất cả các chử số???
    II. Hằng
    Nếu dùng một biến để lưu trữ giá trị của hằng số thì có một vấn đề là biến thì thay đổi được giá trị ==>lỗi.
    VD:
    C++ Code:
    1. float PI=3.14;
    2. //////
    3. PI=8;
    4. //////
    Đ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 chú ý cứ dùng biến đó trên các đ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:
    Có 2 cách khai báo hằng
    - Dùng chỉ thị #define:
    Code:
    #define A "gia tri"
    tác dụng: định nghĩa macro A đại diện cho giá trị dùng để thay thế A trong đoạn mã trừ những đoạn trong "" thành giá trị.
    chỉ thị #define còn có nhiều tác dụng khác.
    - Dùng từ khóa const:
    Code:
    const kiểu tên_hằng=giá_trí;
    kiểu const tên_hằng=giá_trí;
    VD:
    C++ Code:
    1. 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 thể thay đổi x, ví dụ:
    C++ Code:
    1. x=8; //lỗi
    Câu lệnh trên báo lỗi vì ta cố gắng 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:
    C++ Code:
    1. const int x=8;
    2. 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 tác dụng nào không?
    Câu trả lời 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:
    C++ Code:
    1. int x = 10, y = 20;
    2. const int *px = &x;
    Khai báo như vậy, giá trị của vùng nhớ mà px đang trỏ đến là không thể thay đổi được thông qua thay đổi (*px). Do đó, ta có các câu lệnh sau:
    C++ Code:
    1. *px = 15;// lỗi
    2. px = &y;
    3. x = 16;
    Con trỏ này gọi là con trỏ hằng

    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 có thể được thay đổi, ta chỉ không thể thay đổi giá trị này thông qua px.
    Nhưng với các khai báo sau:
    C++ Code:
    1. int x = 10, y = 20;
    2. int* const px = &x;
    Thì px không thể thay đổi vùng nhớ đang trỏ đến, nhưng giá trị của vùng nhớ có thể thay đổi thông qua px
    C++ Code:
    1. *px=y;
    2. *px=&y;//lỗi
    Con trỏ này gọi là hằng con trỏ

    Với khai báo sau:
    C++ Code:
    1. int x = 10;
    2. const int* const px = &x;
    Bạn không thể thay đổi nơi px đang trỏ đến và thông qua (*px) cũng không thể thay đổi 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:
    C++ Code:
    1. class A
    2. {
    3.     int a;
    4. public:
    5.     A(int t=0){a=t;}
    6.     //...
    7. };
    a. Hằng đối tượng
    Để khai báo hằng đối tượng ta dùng từ khóa const như sau:
    C++ Code:
    1. A const a(4);
    2. const A b;
    Ta không thể thay đổi giá trị các thuộc tính của hằng đối tượng, kể cả thông qua con trỏ.
    VD: ta có hàm sau
    C++ Code:
    1. void A::set(int x)
    2. {
    3.     a=x;
    4. }
    Thì ta không thể dùng hàm này để thay đổi giá trị của hằng đối tượng lớp A.
    b. Tham chiếu hằng, con trỏ hằng
    Giả sử có hàm có đối tượng đầu vào sau
    Code:
    type C(A a)
    {
    	//Các câu lệnh
    }
    Một đối tượng object sẽ được tạo và máy sẽ copy toàn bộ giá trị của a vào object rồi xử lý. Vấn đề phát sinh là khi ta có một class với kích thước 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 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 tình 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:
    Code:
    type C(A *a)
    {
    	//Các câu lệnh
    }
    hoặc
    Code:
    type C(A &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 có thể bị thay đổi thông 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:
    Code:
    type C(const A *a)
    {
    	//Các câu lệnh
    }
    Code:
    type C(const A &a)
    {
    	//Các câu lệnh
    }
    Lưu ý: 1. dạng khai báo A const &a không còn được khuyến khích.
    2. Hàm trả về con trỏ có thể có dạng
    C++ Code:
    1.     const A* functionName(/*các đối số*/);
    hay
    C++ Code:
    1.     A const * functionName(/*các đối số*/);
    hay
    C++ Code:
    1.     const A *const  functionName(/*các đố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 thức hằng, vậy phương thức hằng là gì? Tác dụng của nó?
    Như ta đã biêt, một hằng đối tượng thì không thể thay đổi các thuộc tính của nó và không được phép gọi các phương thức có thể làm thay đổi các thuộc tính của nó, trừ trường hợp đặc biệt: các thuộc tính mutable. các phương thức được các hằng đối tượng sử dụng gọi là phương thức hằng, hay nói cách khác, các hằng đối tượng chỉ làm việc trên các phương thức hằng.
    Giả sử với lớp A có một phương thức print() như sau:
    C++ Code:
    1. class A
    2. {
    3.     int a;
    4. public:
    5.     A(int t=0){a=t;}
    6.     //...
    7.     void print();
    8. };
    C++ Code:
    1. void A::print()
    2. {
    3.     cout<<a;
    4. }
    Ta thấy phương thức này không hề làm thay đổi các thuộc tính của a, Nhưng nó không thể làm việc được với hằng đối tượng.
    Giả sử ta có 2 câu lệnh sau:
    C++ Code:
    1. const A a;
    2. 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 thay đổi thuộc tính???
    Lí do là trình dịch không thể biết được là ta có thay đổi thuộc tính hay không ở phương thức không hằng vì một phương thức không hằng có thể thay đổi được thuộc tính.
    Vậy làm sao để có thể cho hàm trên thực hiện được với hằng đối tượng?
    Ta phải khai báo hàm print() là một phương thức 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:
    C++ Code:
    1. void print() const;
    Khi đó print() trở thành mọt phương thức hằng và lớp A Cần được khai báo như sau:
    C++ Code:
    1. class A
    2. {
    3.     int a;
    4. public:
    5.     A(int t=0){a=t;}
    6.     //...
    7.     void print() const;
    8. };
    Khi đó 2 câu lệnh này sẽ chạy được:
    C++ Code:
    1. const A a;
    2. a.print();//////OK
    Nếu ta thay đổi một thuộc tính của đối tượng thuộc lớp A thông qua phương thức print() thì sẽ có lỗi.
    VD:
    C++ Code:
    1. void A::print()
    2. {
    3.     cout<<a;
    4.     a=7; //////lỗi
    5. }
    Vì ta cố gắng thay đổi thuộc tính thông qua phương thức print() là một phương thức hằng.
    Điều này khá hay trong môi trường làm việc cộng tác. Nếu nhiều người cùng xây dựng một lớp: thì cần xác định cái gì cần thay đổi, thay đổi bằng phương thức 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 thức hằng thì không được thay đổi các thuộc tính của đối tượng gọi nó. nhưng đôi khi cần phải thay đổi các thuộc tính này thông qua phương thức hằng, kể cả hằng đối tượ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 thức hằng trả về một con trỏ không thể thay đổi giả trị của vùng nhớ, cũng như vùng nhớ mà con trỏ ấy đang trỏ tới, có tham số đầu vào là một con trỏ cũng không thể thay đổi 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:
    C++ Code:
    1.     const A *const  functionName(const A * const) const; //5 từ const!!

    UPDATE
    trong C++ giả sử có hàm:
    Code:
    type1 ham(type&);//không thay đổi đối số trong thân hàm nha
    Khi đó bạn gọi hàm như sau
    Code:
    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
    Code:
    type1 ham(const type&);/////////
    khi đó lời gọi hàm trên có tác dụng

    Về con trỏ hằng và hằng con trỏ, tham khảo topic: Bản đồ box hướng dẫn (update daily)
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Đã được chỉnh sửa lần cuối bởi trungkien45 : 03-12-2016 lúc 01:01 PM. Lý do: Update nhỏ

  2. #2
    Ngày gia nhập
    12 2010
    Nơi ở
    Mây
    Bài viết
    268

    - Rất bổ ích, rất chi tiết. Cảm ơn bạn nhiều
    - Nhưng câu Nếu dùng một biến để lưu trữ giá trị của hằng số thì có một vấn đề là biến thì thay đổi được giá trị ==>lỗi. là sao ?????
    - Lêu lêu

  3. #3
    Ngày gia nhập
    03 2009
    Nơi ở
    Ở địa ngục
    Bài viết
    667

    Trích dẫn Nguyên bản được gửi bởi ncptbl Xem bài viết
    - Rất bổ ích, rất chi tiết. Cảm ơn bạn nhiều
    - Nhưng câu Nếu dùng một biến để lưu trữ giá trị của hằng số thì có một vấn đề là biến thì thay đổi được giá trị ==>lỗi. là sao ?????
    Lỗi ở chỗ cậu không biết đâu mà lần, nếu cậu thay đổi biến PI thì nếu cậu cần dùng lại số π thì sao==> kết quả sai OK?

  4. #4
    Ngày gia nhập
    02 2010
    Bài viết
    17

    Cảm ơn bạn, bài viết rất hay và chi tiết ^_^

  5. #5
    Ngày gia nhập
    08 2010
    Bài viết
    82

    Bài viết rất hay. Nhưng bạn bảo nếu có đoạn mã
    float PI=3.14;
    //////
    PI=8;
    //////
    không báo lỗi là sai đó
    bạn thử chạy thử trong TC 3.0 xem, sẽ báo lỗi Lvalue Required
    thế nhá.

  6. #6
    Ngày gia nhập
    03 2009
    Nơi ở
    Ở địa ngục
    Bài viết
    667

    Mặc định Cách sử dụng từ khóa const trong C++

    Trích dẫn Nguyên bản được gửi bởi soldtheworld Xem bài viết
    Bài viết rất hay. Nhưng bạn bảo nếu có đoạn mã
    float PI=3.14;
    //////
    PI=8;
    //////
    không báo lỗi là sai đó
    bạn thử chạy thử trong TC 3.0 xem, sẽ báo lỗi Lvalue Required
    thế nhá.
    Xin lỗi, bạn đưa code full của bạn lên, mình không thấy có lỗi gì ở đây cả, mình thử bằng TC 3.0 rồi

  7. #7
    Ngày gia nhập
    09 2012
    Bài viết
    1

    thaks bạn nhiều. Bài viết rất hay.

  8. #8
    Ngày gia nhập
    02 2012
    Bài viết
    2

    Kiến thức rất hay và bổ ích, rất cảm ơn anh đã chia sẽ

  9. #9
    Ngày gia nhập
    04 2013
    Nơi ở
    Hà Nội
    Bài viết
    4

    cái này hay quá. Mình đang tìm hiểu về nó may mà gặp. thanhks bạn nhiều nhé!

  10. #10
    Ngày gia nhập
    05 2009
    Nơi ở
    Tp Hồ Chí Minh
    Bài viết
    16

    Trích dẫn Nguyên bản được gửi bởi trungkien45 Xem bài viết
    b. Tham chiếu hằng, con trỏ hằng
    Giả sử có hàm có đối tượng đầu vào sau
    Code:
    type C(A a)
    {
    	//Các câu lệnh
    }
    Một đối tượng object sẽ được tạo và máy sẽ copy toàn bộ giá trị của a vào object rồi xử lý. Vấn đề phát sinh là khi ta có một class với kích thước 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 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 tình 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:
    Code:
    type C(A *a)
    {
    	//Các câu lệnh
    }
    hoặc
    Code:
    type C(A &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 có thể bị thay đổi thông 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:
    Code:
    type C(const A *a)
    {
    	//Các câu lệnh
    }
    Code:
    type C(const A &a)
    {
    	//Các câu lệnh
    }
    Lưu ý: 1. dạng khai báo A const &a không còn được khuyến khích.
    Nếu muốn thay đổi giá trị của biến a thì vẫn được bằng cách sử dụng const_cast trong C++.
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Hãy vội vã một cách từ từ!

Các đề tài tương tự

  1. Lập trình C++0x const: ý nghĩa của const trong khai báo function
    Gửi bởi quano1 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 13
    Bài viết cuối: 06-08-2013, 07:24 AM
  2. Tìm hiểu về từ khóa const - const với nhiều ý nghĩa
    Gửi bởi langman trong diễn đàn Tutorials và Thủ thuật Visual C++
    Trả lời: 1
    Bài viết cuối: 19-12-2011, 12:00 PM
  3. Kỹ thuật C++ Thắc mắc từ khóa const trước hàm
    Gửi bởi cab8nwf6hgpc trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 4
    Bài viết cuối: 18-09-2010, 11:34 AM
  4. [VC++] - Hỏi hàm có gắn từ khóa const phía sau
    Gửi bởi vuongngocnam trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 7
    Bài viết cuối: 04-05-2010, 06:18 PM
  5. [ Solved ]Cho em hỏi về từ khóa const.
    Gửi bởi trunkthai trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 1
    Bài viết cuối: 19-09-2008, 02:50 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn