Lập trình C++ - Lớp bạn

Lớp bạn trong C++

Khi tất cảc các phương thức của một lớp là bạn của một lớp khác, thì lớp của các phương thức đó cũng trở thành lớp bạn của lớp kia. Muốn khai báo một lớp B là lớp bạn của lớp A.

Lớp friend được xây dựng để khắc phục điểm yếu lớp dẫn xuất không thể truy cập tới các biến private của lớp cơ sở.

  1. Định nghĩa:
    • Một friend có thể là một hàm, một mẫu hàm, hoặc hàm thành viên, hoặc một lớp hoặc một mẫu lớp, trong trường hợp này, toàn bộ lớp và tất cả thành viên của nó là friend.

    • Hàm friend trong C++ của một lớp được định nghĩa bên ngoài phạm vi lớp đó, nhưng nó có quyền truy cập tất cả thành viên private và protected của lớp đó. Ngay cả khi các nguyên mẫu cho hàm friend xuất hiện trong định nghĩa lớp, thì các hàm friend không là các hàm thành viên.

  2. Tính chất:

    • Friend của một class có thể là thành viên của 1 class khác
    • Friend của 1 class có thể là thành viên của class khác hoặc tất cả các class trong cùng 1 chương trình. Như là 1 GLOBAL FRIEND
    • Friend có thể access private hoặc protected của class được khai báo là Friend.
    • Friends không phải là một thành viên vì vậy không có con trỏ "this"
    • Friend có thể khai báo ở bất cứ đâu ( public, protected or private section) trong một class.
  3. Khai báo tuần tự theo sau:

  • Khai báo khuôn mẫu lớp B: 
    class B; 

     

  • Định nghĩa lớp A, với khai báo B là lớp bạn: 
    class A{ 
         ...// Khai báo các thành phần của lớp A 
         // Khai báo lớp bạn B     
          friend class B; 
    }; 

     

  •  Định nghĩa chi tiết lớp B: 
    class B{ 
        ... // Khai báo các thành phần của lớp B 
    }; 

     

Lưu ý: 
•    Trong trường hợp này, lớp B là lớp bạn của lớp A nhưng không có nghĩa là lớp A cũng là bạn của lớp B: tất cả các phương thức của lớp B có thể truy nhập các thành phần private của lớp A (thông qua các đối tượng có kiểu lớp A) nhưng các phương thức của lớp A lại không thể truy nhập đến các thành phần private của lớp B. 
•    Muốn các phương thức của lớp A cũng truy nhập được đến các thành phần private của lớp B, thì phải khai báo thêm là lớp A cũng là lớp bạn của lớp B. 


Ví dụ về lớp friend:

class Person
{
private:
   string name;
public:
   friend void DisplayName( Person person); //hàmhiển thị tên
   void setName( string name );
};
  • Để khai báo tất cả hàm thành viên của lớp Employee là dạng friend của lớp Person, đặt một khai báo sau trong định nghĩa của lớp Person:
    class Person
    {
     friend class Employee; // Employee là friend của person
    };

    Như đã nói ở trên
    - Trong lớp dẫn xuất không cho phép truy nhập đến các thuộc tính private của lớp cơ sở.

    Vậy nếu bạn muốn tạo quan hệ giữa 2 class A và B. Sao cho B có thể truy cập các private hay protected của A nhưng bạn không muốn xây dựng các phương thức setter hoặc getter để tránh các class khác ngoài B cũng truy cập được thì làm thế nào?. Đó là truy cập có chọn lọc và từ khóa friend sẽ giúp bạn.

    Ví dụ method friend.

    class Person
    {
    private:
       string name;
    public:
     //Hàm DisplayName không phải thành viên của person mà là Friend. 
    Có thể gọi ở bất cứ đâu trong chương trình
       friend void DisplayName( Person person); 
       void setName( string name );
    };
    
    // phan dinh nghia ham setname
    void Person::setName( string name )
    {
        this->name = name;
    }
    
    // Ghi chu: DisPlayName() khong la ham thanh vien cua bat cu class nao.
    void DisPlayName( Peson person )
    {
       /* Boi vi, ham DisPlayName() la ham friend cua Person, do vay no co the
        truc tiep truy cap bat cu thanh vien nao cua class nay */
        
       cout << "Ten ban la: " << person.name<<endl;
    }
     
    // ham main cua chuong trinh
    int main( )
    {
       Person person;
     
       // set tên cho person  khong su dung ham thanh vien
       person.setName("Tran Thanh Cong");
       
       // su dung ham friend de in ra tên.
       DisPlayName( person);
     
       return 0;
    }

     

Kết quả:

Ten ban la: Tran Thanh Cong