2014-12-10 55 views
2

這是通常的作品,但我使用名稱空間是搞砸了。爲什麼我的班級朋友不能使用名稱空間訪問受保護的成員?

把這個代碼:

.H:

class FetchRecord 
{ 
    friend KxStream& operator<<(KxStream& os, FetchRecord& r); 
protected: 
    int mId; 
}; 

的.cpp:

KxStream& operator<<(KxStream& os, FetchRecord& r) 
{ 
    os << r.mId; 
    return os; 
} 

這工作得很好。但是,如果我做的:

.H:

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& operator<<(KxStream& os, FetchRecord& r); 
    protected: 
     int mId; 
    }; 
} 

的.cpp:

using namespace Blah; 

KxStream& operator<<(KxStream& os, FetchRecord& r) 
{ 
    os << r.mId; 
    return os; 
} 

然後朋友DECL似乎忽略:

src/fetch.cpp:153:25: error: 'mId' is a protected member of 'Blah::FetchRecord' 

我可能知道發生了什麼 - .cpp中的函數與朋友decl中的函數不匹配。你如何解決這個問題?

@更新:現在下面兩個正確的答案。謝謝。經過測試和工作。但我討厭不得不把我的運營商< <函數放在Blah命名空間中。這將是清潔的,如果完全原型的功能是:

KxStream& operator<<(KxStream&, Blah::FetchRecord&); 

也就是說,如果我能以某種方式向前聲明命名空間嗒嗒之外的友元函數。我找到了一種方法:

namespace Blah 
{ 
    class FetchRecord; 
} 

KxStream& operator<<(KxStream& os, Blah::FetchRecord& r); 

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& ::operator<<(KxStream& os, FetchRecord& r); 
    }; 
} 

你必須得到直白。請注意運營商< <的朋友decl中的「::」。

回答

2

在第二種情況下,您在全局名稱空間中定義了operator<<,這與您在.h文件中聲明的內容無關。你應該在namespace Blah定義它:

namespace Blah { 
    KxStream& operator<<(KxStream& os, FetchRecord& r) 
    { 
     os << r.mId; 
     return os; 
    } 
} 

更新:如果你想operator<<屬於全局命名空間(這是奇怪的,因爲由於ADL它的工作即使沒有using namespace Blah),你可以寫在.H以下文件,並留下.cpp文件,因爲它是:

namespace Blah 
{ 
    class FetchRecord; 
} 

KxStream& operator<<(KxStream& os, Blah::FetchRecord& r); 

namespace Blah 
{ 
    class FetchRecord 
    { 
     friend KxStream& ::operator<<(KxStream& os, FetchRecord& r); 
     //    ^^^^ 
    protected: 
     int mId; 
    }; 
} 
+0

正確和工作。但我希望有另一種方式。我不喜歡我的operator << function在Blah命名空間中。 – 2014-12-10 22:32:22

+0

@RafaelBaptista你爲什麼不喜歡它? – 2014-12-10 22:45:48

+0

哈哈。恰恰是我剛剛在我的問題更新中發佈的內容。 – 2014-12-10 22:48:00

1

儘管using namespace Blah,你還需要定義函數的時候,因爲Blah是在其被宣佈命名空間限定名稱。它應該是:

KxStream& Blah::operator<<(KxStream& os, FetchRecord& r) 
+0

正確和有效。但我希望有另一種方式。我不喜歡我的operator << function在Blah命名空間中。 – 2014-12-10 22:32:05

+1

@RafaelBaptista然後在將它聲明爲朋友之前,在名稱空間之外聲明它。 – 0x499602D2 2014-12-10 22:32:49

+0

找不到一個不太難看的方法。例如。正常的轉發和gcc處理爲兩個不同的功能。 – 2014-12-10 22:40:01

相關問題