1. Kết quả Event Ghost 2016


    Dưới đây là danh sách những thành viên đoạt giải thưởng trong Event Ghost 2016

Phân biệt giữa con trỏ và tham chiếu trong C++

Thảo luận trong 'Pascal, C , C++' bắt đầu bởi No Nguyễn, 7 Tháng ba 2012.


  1. No Nguyễn

    No Nguyễn Admin Ban Quản Trị

    1,408
    2,079
    213
    Tên thật:
    Nguyễn Văn Trung
    [​IMG]

    Con trỏ (pointer) và tham chiếu (reference) trong C++ thoạt nhìn là khác nhau như: con trỏ sử dụng các toán tử “*” và “->”, còn tham chiếu sử dụng “.”. Nhưng chúng dường như được dùng để làm những điều tương tự nhau. Cả con trỏ và tham chiếu đều cho phép bạn truy cập đến các đối tượng gián tiếp khác. Như vậy làm thế nào để biết khi nào thì nên dùng con trỏ và khi nào thì dùng tham chiếu?

    1. Tham chiếu đến “null”

    - Đầu tiên bạn nên biết là không có một tham chiếu null. Một tham chiếu phải luôn chỉ đến một đối tượng nào đó.
    - Ví dụ như, nếu bạn có một biến mà mục tiêu là tham chiếu một đối tượng khác, nhưng nó có thể không có một đối tượng tham chiếu (tham chiếu null). Trường hợp này bạn nên sử dụng con trỏ (pointer) vì sau đó bạn có thể thiết lập giá trị của nó là null.
    - Mặc khác, nếu biến luôn phải chỉ đến một đối tượng, nghĩa là nếu thiết kế của bạn không cho phép khả năng biến đó có giá trị null, thì nên sử dụng tham chiếu cho trường hợp này.
    - Hãy xem xét đoạn code sau:

    char *pc = 0; // thiết lập con trỏ null
    char& rc = *pc; // tạo một tham chiếu chỉ đến con trỏ null


    Đây là một trường hợp tồi tệ và kết quả là không xác định (trình biên dịch có thể cho ra output là bất cứ cái gì), và những ai viết đoạn mã trên bị tẩy chay cho đến khi họ chịu ngừng và chấm dứt cách viết đó. Nếu bạn lo lắng về một điều tương tự điều này trong phần mềm của bạn, thì bạn nên tránh sử dụng tham chiếu trong trường hợp này, hoặc có thể tìm một lớp tốt hơn để làm việc với nó. Do đó, chúng ta sẽ bỏ qua khả năng tham chiếu có thể là “null”.
    2. Khởi tạo (initialization)
    - Vì tham chiếu phải truy cập đến một đối tượng, do đó C++ yêu cầu các tham chiếu phải được khởi tạo.

    string& rs; // Lỗi! tham chiếu phải được khởi tạo
    string s("xyzzy");
    string& rs = s; // rs tham chiếu đến s


    - Đối với con trỏ thì điều đó là hợp lệ, nhưng nó cũng chứa những rủi ro.


    string *ps; // con trỏ chưa được khởi tạo giá trị. Điều này hợp lệ nhưng hàm chứa rủi ro.


    3. Tính hợp lệ (validation)
    - Trên thực tế, không có điều gì là một tham chiếu null, nghĩa là việc sử dụng tham chiếu tỏ ra hiệu quả hơn so với con trỏ. Điều đó thể hiện qua việc không cần phải kiểm tra tính hợp lệ của một tham chiếu trước khi sử dụng nó. Ví dụ như:

    void printDouble(const double& rd)
    {
    cout << rd; // không cần phải kiểm tra rd;
    } // nó phải tham chiếu đến một biến double

    - Còn đối với con trỏ, bạn phải kiểm tra nó có null hay không trước khi sử dụng.

    void printDouble(const double *pd)
    {
    if (pd) { // kiểm tra con trỏ có null hay không cout << *pd;
    }
    }


    4. Truy cập đến các đối tượng khác nhau:
    - Một trong những khác biệt quan trọng giữa con trỏ và tham chiếu là con trỏ có thể được chỉ định để truy cập đến các đối tượng khác nhau. Còn một tham chiếu chỉ truy cập đến các đối tượng đã được khởi tạo cho nó.

    string s1("Khue");
    string s2("Cuong");
    string& rs = s1; // rs tham chiếu đến s1. string *ps = &s1; // con trỏ ps trỏ đến s1rs = s2; // rs vẫn tham chiếu đến s1
    // nhưng giá trị của s1 bây giờ là: "Cuong”. ps = &s2; // ps trỏ đến s2
    // s1 không thay đổi


    - Nói chung, bạn có thể sử dụng con trỏ(pointer) bất cứ khi nào bạn cần đến khả năng trỏ đến null hay bất cứ khi nào bạn cần để có thể trỏ đến những thứ khác nhau ở những thời điểm khác nhau. BẠn nên sử dụng tham chiếu (reference) bất cứ khi nào bạn luôn có một đối tượng để chỉ tới , và bạn cũng không bao giờ cần trỏ nó tới bất cứ một điều gì khác.
    * Có một tình huống khác mà trong đó bạn nên sử dụng tham chiếu (reference) là khi bạn đang triển khai một các toán tử. Ví dụ phổ biến nhất là toán tử []. Toán tử này thường trả lại một cái gì đó để được sử dụng như một phép gán.

    vector<int> v(10); // Tạo một vector kiểu int với kích thước 10
    // standard C++ library
    v[5] = 10; // Mục tiêu của phép gán là trả về giá trị của toán tử [5]

    Nếu toán tử [] trả về là một con trỏ, dòng khai báo thứ 2 phải được viết là:
    *v[5] = 10;
    nhưng điều này làm cho v giống như là một vector của con trỏ, mặc dù không phải vậy. Vì lý do đó, hầu như bạn luôn cần một toán tử [] trả về một tham chiếu.
    Tham chiếu là một lựa chọn tốt khi bạn biết chắc rằng có một thứ gì đó để bạn tham chiếu đến. Nó tỏ ra rất hữu ích trong rất nhiều trường hợp. Nhưng trong thực tế chúng ta vẫn gắn bó với con trỏ trong nhiều trường hợp hơn là tham chiếu.
    (Tham khảo cplusplus.com)

     
    tiennui3009 thích bài này.

Chia sẻ trang này