定义名称空间内的类的友元函数的定义。

时间:2011-07-28 21:52:42

标签: c++ namespaces friend

我正在阅读C ++ Primer,作者说,

  

“如果在命名空间内定义了一个类,那么另外一个   未申报的朋友         function在同一名称空间中声明:

      namespace A {
        class C {
          public:
            friend void f(const C&); // makes f a member of namespace A
        };
      }

这不是说我不必在命名空间内再次声明函数f()吗?

当我简单地将命名空间外的函数f()定义为

void
A::f(const C& obj)
{
  std::cout << "f(const C&) " << std::endl;
}

我从g ++ 4.5中得到错误,

FriendDeclarations1.cpp:40:23: error: ‘void A::f(const A::C&)’ should have been declared inside ‘A’

有人可以告诉我作者的意思吗?

3 个答案:

答案 0 :(得分:3)

作者的意思是如果未明确声明其名称空间,则在同一个类名称空间中隐式声明friend函数。

因此f需要在命名空间A

中定义
#include <iostream>

namespace A {
  class C {
    friend void f(const C&); // makes f a member of namespace A
    int i;

    public:
      C() : i(42) {}
  };

  void f(const A::C& obj)
  {
    std::cout << "f(const A::C&) " << std::endl;
    std::cout << "obj.i = " << obj.i << std::endl;      // access private member
  }
}

int main()
{
  A::C ac;

  f(ac);
  return 0;
}

您可以通过明确声明f所属的命名空间

来更改此行为
#include <iostream>

// forward declarations
namespace A { class C; }
namespace B { void f(const A::C&); }

namespace A {
  class C {
    friend void B::f(const C&);
    int i;

  public:
    C() : i(42) {}
  };
}

namespace B {
  void f(const A::C& obj)
  {
    std::cout << "f(const A::C&) " << std::endl;
    std::cout << "obj.i = " << obj.i << std::endl;      // access private member
  }
}

int main()
{
  A::C ac;

  B::f(ac);
  return 0;
}

答案 1 :(得分:2)

标准7.3.1.2 / 3:

首先在名称空间中声明的每个名称都是该名称空间的成员。如果朋友申报了 非本地类首先声明一个类或函数83)友元类或函数是最里面的成员 封闭命名空间。 在该命名空间范围内(在授予友谊的类声明之前或之后)之前或之后,通过简单的名称查找找不到朋友的姓名。

答案 2 :(得分:0)

对于类声明,您所拥有的内容被解释为类成员定义:

class A {
  void f(const C& obj);
}

你应该这样定义:

namespace A {
  void f(const C& obj)
  {
    std::cout << "f(const C&) " << std::endl;
  }
}
相关问题