2012-06-07 28 views
9

Im cố gắng để xác định một chức năng lớp người bạn bên ngoài không gian tên như thế này:lớp người bạn chức năng bên trong một không gian tên

namespace A{ 
class window{ 
    private: 
    int a; 
    friend void f(window); 
}; 
} 

void f(A::window rhs){ 
cout << rhs.a << endl; 
} 

Im nhận được một lỗi nói rằng có sự mơ hồ. và có hai ứng viên void A::f(A::window);void f(A::window). Vì vậy, câu hỏi của tôi là:

1) Cách tạo hàm toàn cục void f(A::window rhs) một người bạn của lớp A :: cửa sổ.

EDIT: (Sau khi đọc các câu trả lời)

2) tại sao tôi cần phải hội đủ điều kiện chức năng thành viên f bên trong lớp cửa sổ là toàn cầu bằng cách làm ::f(window)?

3) tại sao tôi cần đặt trước hàm f (A :: window) trong trường hợp cụ thể này, trong khi lớp không được định nghĩa bên trong một không gian tên, nó là okey cho hàm được khai báo sau khi hàm được khai báo một người bạn.

Trả lời

15

Cũng như thêm một :: bạn cần để chuyển tiếp tuyên bố nó, ví dụ .:

namespace A { class window; } 

void f(A::window); 

namespace A{ 
    class window{ 
    private: 
    int a; 
    friend void ::f(window); 
    }; 
} 

void f(A::window rhs){ 
    std::cout << rhs.a << std::endl; 
} 

Lưu ý rằng đối với tờ khai chuyển tiếp này để làm việc bạn cần để chuyển tiếp khai báo lớp quá!

+0

nên :: prefix để truy cập namespace toàn cầu là một trong những đòi hỏi trước tuyên bố chức năng void f (A :: cửa sổ); điều này có đúng không. cảm ơn trước. – AlexDan

+0

Có tác dụng này khi hàm trả về void. Nhưng nếu nó trả về một thể hiện của một lớp, hãy nói B? Sau đó, các trình biên dịch barfs trên "người bạn B :: f()" bởi vì nó nghĩ rằng chúng tôi có nghĩa là "B :: f()" (tức là một chức năng của lớp B, như trái ngược với một chức năng toàn cầu). Bất kỳ giải pháp cho điều đó? –

+0

Tôi không thấy làm thế nào bạn có thể kết thúc với một cuộc đụng độ tên như vậy một cách hợp pháp - bạn có thể hiển thị nó trên một cái gì đó như ideone? – Flexo

4

này nên làm điều đó: bạn cần về phía trước tuyên bố để làm cho nó rõ ràng f là trong không gian tên toàn cầu (và không phải nộp tĩnh):

#include <string> 
#include <iostream> 

using namespace std; 

////// forward declare magic: 

namespace A{ class window; }  
void f(A::window rhs); 

////// 

namespace A { 
    class window { 
     private: 
      int a; 
      friend void ::f(window); 
    }; 
} 

void f(A::window rhs) { 
    cout << rhs.a << endl; 
} 

int main() 
{ 
} 
Các vấn đề liên quan