Một hàm cũng có thể là bạn của một lớp. Hàm như vậy có thể truy cập vào tất cả các thành phần private và protected của lớp.
Các quy tắc về hàm bạn hơi khác với quy tắc về lớp bạn:
- một khai báo hàm bạn phải chứa một nguyên mẫu đầy đủ của hàm (bao gồm cả tham số và kiểu trả về); một hàm có cùng tên, nhưng không tương thích về tham số và kiểu trả về sẽ không được công nhận là một hàm bạn
- một lớp có thể có nhiều hàm bạn
- một hàm có thể là bạn của nhiều lớp
- một lớp có thể nhận cả hàm toàn cục và hàm thành viên (của class khác) là bạn
Hãy xem ví dụ sau →
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <iostream> using namespace std; class A; class C { public: void dec(A &a); }; class A { friend class B; friend void C::dec(A&); friend void DoIt(A&); private: int field; protected: void print(void) { cout << "It's a secret, that field = " << field << endl; } }; void C::dec(A &a) { a.field--; } class B { public: void DoIt(A &a) { a.print(); } }; void DoIt(A &a) { a.field = 99; } int main(void) { A a; B b; C c; DoIt(a); b.DoIt(a); return 0; } |
Lớp A có ba người bạn. Đó là
- lớp B
- hàm toàn cục DoIt ()
- hàm thành viên dec (của lớp C)
Lưu ý dòng:
class A;
ở đầu chương trình. Nó không làm gì ngoại trừ thông báo cho trình biên dịch rằng một lớp có tên là A sẽ được sử dụng. Nếu thiếu dòng này sẽ gây ra lỗi biên dịch vì trình biên dịch sẽ không nhận thức được sự tồn tại của lớp A khi phân tích phần thân của lớp C. Cái này gọi là Forward Declaration.
Chương trình trên sẽ output ra →
1 |
It's a secret, that field = 99 |