1

我正在尝试与一个类成为朋友,以便它能够访问它的私有构造函数。

在 some_file.h

class B;    

namespace some_name {
class A {
  public:
    A() {}
  private:
    A (int x) {}
    friend class ::B;
};
}

在 other_file.h

#include "some_file"

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x); }
};   
}

编译此代码时,我得到 - 错误:'some_name::A::A(int)' is private。

我现在,它是私人的,这就是我与 B 成为朋友的原因。我在这里做错了什么?你不能和你的构造函数交朋友吗?有命名空间问题吗?

谢谢

4

4 回答 4

9

这样做:

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x) };
}   
}

您没有放入B根(全局)命名空间,而是放入匿名命名空间。

所以B无法到达::B

如果您想B位于根(全局)命名空间中,请不要将其包含namespace在其中。这应该可以解决问题。

于 2010-08-25T14:55:29.440 回答
1

您只在全局命名空间中转发声明和交友的类 B。不是命名空间中的 B 类。您需要完全限定 B 的名称。

编辑:谢谢ereOn。
我犯了一个小错误。确实,您遇到问题的原因是因为您错误地声明和错误地引用了 B,但我最初的陈述并不完全正确。您需要将 B 从匿名命名空间中取出 - 无论如何,放在标题中是没有意义的。

于 2010-08-25T14:55:53.833 回答
0

The problem is that you refer to B as ::B instead of B. Meaning, you're telling the compiler that B is a global name, but in fact it isn't: it's inside an anonymous namespace. You don't have to remove the anonymous namespace, it's just that it may not do what you expect it to do. Because the anonymous namespace is in a header it means what's inside that namespace is linked statically to any implementation file that includes the header. That's not very useful, because you hide nothing. You might as well remove that anonymous namespace.

于 2010-08-25T15:09:26.027 回答
0

你不能和你的构造函数交朋友吗?

你可以如下图

struct B{
    B();
    void f();
};

struct A{
    friend B::B();
private:
    A(){}
};

B::B(){A a;}       // fine

void B::f(){A a;}  // error

int main(){
}
于 2010-08-25T15:14:07.863 回答