Khi trình biên dịch bắt đầu biên dịch mã (thường là từ trên) và nó gặp dòng này:
friend void B::fB(A& a);
- vào thời điểm này, trình biên dịch không có ý tưởng về thông tin loại B nên nó ném một lỗi ('B': không phải là tên lớp hoặc không gian tên).
bằng cách khai báo chuyển tiếp của lớp B, trình biên dịch biết về loại B là Lớp trước để khai báo thực tế với tất cả các thành viên.
chạy bên dưới mã sau khi tờ khai phía trước của lớp B.
///////////////
class B;
class A
{
public:
friend void B::fB(A& a);
void fA(){};
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
Tuy nhiên lỗi !!!
vì khai báo chuyển tiếp chỉ là khai báo số nhận dạng mà lập trình viên chưa đưa ra định nghĩa đầy đủ. do đó trình biên dịch cần định nghĩa đầy đủ của B trước lớp A.
Lưu ý: lớp A phụ thuộc vào kiểu B và định nghĩa của B (tức là B :: fB) để tự khai báo chuyển tiếp. B cần phải xác định trước khi đến lớp A.
4 chạy mã này
////////
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
Tuy nhiên lỗi !!!
vì chức năng thành viên lớp B FB & FB2 có đối số loại A nhưng trình biên dịch không có ý tưởng về thông tin loại A như vậy theo tờ khai phía trước của lớp A, chúng ta có thể để cho trình biên dịch biết về thông tin loại A. Lưu ý: lớp định nghĩa B chỉ phụ thuộc vào loại của A không phải là thành viên của A sao cho tờ khai chuyển tiếp của A bước quyết tâm 4.
- mã cuối cùng
////// //////////////////
class A; // forward declaration of A needed by B
class B
{
public:
void fB(A& a);
};
class A
{
int i;
public:
friend void fA(A& a); //specifying function fA as a friend of A, fA is not member function of A
friend void B::fB(A& a); //specifying B class member function fB as a friend of A
};
// fA is Friend function of A
void fA(A& a)
{
a.i = 11; // accessing and modifying Class A private member i
cout<<a.i<<endl;
}
// B::fB should be defined after class A definition only because this member function can access Class A members
void B::fB(A& a)
{
a.i = 22; // accessing and modifying Class A private member i in Class B member function fB
cout<<a.i<<endl;
}
int main()
{
A a;
fA(a); // calling friend function of class A
B b;
b.fB(a); // calling B class member function fB, B:fB is friend of class A
return 0;
}
6 Bài tập:
// Cyclic dependency
#include<iostream>
using namespace std;
class A;
class B
{
public:
void fB(A& a);
friend void A::fA(B& b); //specifying class A's member function fA as a friend of B
};
class A
{
int i;
public:
void fA(B& b);
friend void B::fB(A& a); //specifying class B's member function fB as a friend of A
};
int main()
{
return 0;
}
Nhưng nếu trong FB (A & a) Tôi sử dụng một để truy cập biến trong Một ví dụ, a.variable; điều đó sẽ là bất hợp pháp vì A chưa được xác định. – ipkiss
@ipkiss có, bởi vì sau đó bạn sẽ cần định nghĩa đầy đủ nếu bạn có trong khai báo lớp tiêu đề. Nhưng nếu bạn đã làm nó trong một tập tin thực hiện riêng biệt, bạn có thể bao gồm các tuyên bố đầy đủ của A. – juanchopanza