为什么我的类朋友函数不能访问具有命名空间的受保护成员?

时间:2014-12-10 22:22:47

标签: c++ namespaces

这通常有用,但我使用命名空间搞砸了。

拿这段代码:

·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;
}

然后朋友拒绝似乎被忽略了:

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

我可以告诉可能发生了什么 - .cpp中的函数与朋友decl中的函数不匹配。你是如何解决这个问题的?

@Update:现在下面有两个正确的答案。谢谢。经过测试和工作。但我讨厌不得不把我的算子&lt;&lt; Blah命名空间中的函数。如果功能的完整原型是:

,那将更清洁
KxStream& operator<<( KxStream&, Blah::FetchRecord& );

也就是说,如果我能以某种方式向前声明在名称空间Blah之外的朋友函数。我找到了一种方法:

namespace Blah
{
   class FetchRecord;
}

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

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

你必须得到一丝不苟言辞。注意&#34; ::&#34;在运营商&lt;&lt;。

的朋友decl中

2 个答案:

答案 0 :(得分: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;
    };
}

答案 1 :(得分:1)

尽管using namespace Blah,您仍然需要在定义函数时限定名称,因为Blah是声明它的名称空间。它应该是:

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