Lớp bạn(Friend) và lớp dẫn xuất(Deliver) trong C++

I. Lớp dẫn xuất
Định nghĩa lớp dẫn xuất:

  • Một lớp được xây dựng thừa kế một lớp khác được gọi là lớp dẫn xuất; lớp dùng để xây dựng lớp dẫn xuất được gọi là lớp cơ sở.
  • Một lớp dẫn xuất ngoài các thành phần riêng của lớp đó, còn được thừa kế các thành phần của các lớp cơ sở có liên quan

Cách xây dựng lớp dẫn xuất

  • Giả sử ta đã xây dựng lớp A, B. Để xây dựng lớp C kế thừa public các lớp A và B, ta viết theo mẫu sau:
 class C: public A, public B
 {
       private:
               //Cac thuoc tinh
       public:
               //Cac phuong thuc
 };

Tương tự, ta thay từ khóa public băng private để C kế thừa private từ A và B

Tính chất:
Kế thừa theo kiểu public thì tất cả các thành phần public của lớp cơ sở sẽ là thành phần public của lớp dẫn xuất.
Kế thừa theo kiểu private thì tất cả các thành phần public của lớp cơ sở sẽ là thành phần private của lớp dẫn xuất.

Thừa kế các thuộc tính

Các thuộc tính của lớp cơ sở sẽ được thừa kế trong lớp dẫn xuất. Như vậy thì tập thuộc tính của lớp dẫn xuất sẽ gồm: các thuộc tính mới khai báo trong định nghĩa lớp dẫn xuất và các thuộc tính của lớp cơ sở.

Tuy nhiê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ở.
ref

II . Lớp Friend
Mục đích:
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.
  1. 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.
  1. Khai báo
  • Để khai báo một hàm dạng hàm friend của một lớp, đặt trước nguyên mẫu hàm đó trong định nghĩa lớp với từ khóa friend trong C++, như sau:
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
};

Giờ là điểm thực sự khác nhau giữa Friend(Bạn) và Deliver(Dẫn xuất).

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 );
};

```java
// phan dinh nghia ham setname
void Person::setName( string name )
{
    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 << "Tên của bạn là: " << 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("Đỗ Trung Quân");
   
   // su dung ham friend de in ra tên.
   DisPlayName( person);
 
   return 0;
}

output: -> Tên của bạn là: Đỗ Trung Quân
ref

Như bạn thấy, mình có thể truy cập được biến private name của class person từ method main.

6 Likes

Nếu như mình muốn khai báo:

friend void QuanLy::NhapTen(string name)

thì có được không?
tức là hàm nhập tên này thuộc class QuanLy

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?