2014-12-10 84 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

相关问题