简体   繁体   English

结识同学

[英]Befriending a class

I am trying to befriend a class in order for it to be able to reach a private constructor of it. 我试图与一个类成为朋友,以使其能够到达它的私有构造函数。

In some_file.h 在some_file.h中

class B;    

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

In other_file.h 在other_file.h中

#include "some_file"

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

When compiling this code, I get - error: 'some_name::A::A(int)' is private. 编译此代码时,我得到-错误:“ some_name :: A :: A(int)”是私有的。

I now, it is private, this is why I befriended B. What am I doing wrong here? 我现在是私人的,这就是为什么我成为朋友B。我在这里做错了什么? Can't you befriend your constructor? 你不能和你的构造函数做朋友吗? Is there a namespace issue? 是否存在名称空间问题?

Thanks 谢谢

Doing this: 这样做:

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

You're not putting B in the root (global) namespace but in an anonymous one. 您不是将B放在根(全局)名称空间中,而是放在匿名名称空间中。

So B can't be reached by ::B . 因此B不能达到::B

If you want B to be in the root (global) namespace, just don't enclose it with namespace at all. 如果希望B在根(全局)名称空间中,则根本不要将其用namespace括起来。 This should do the trick. 这应该可以解决问题。

You only forward declared and friended a class B in the global namespace. 您只能在全局名称空间中转发已声明并成为B类的朋友。 Not a class B in a namespace whatever. 命名空间中都不是B类。 You need to fully qualify the name of B. 您需要完全限定B的名称。

Edit: Thanks ereOn. 编辑:谢谢ereOn。
I made a slight mistake. 我犯了一个小错误。 It's true that the reason that you've got a problem is because you've mis-declared and mis-referred-to B, but my original statement wasn't quite true. 确实,您遇到问题的原因是因为您对B的错误声明和错误引用,但我的原始说法并不完全正确。 You need to take B out of the anonymous namespace - it's pointless being in a header anyway. 您需要将B从匿名名称空间中删除-无论如何,将B放在标题中是毫无意义的。

The problem is that you refer to B as ::B instead of B . 问题是您将B称为::B而不是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. 意思是,您要告诉编译器B是全局名称,但实际上并非如此:它在匿名名称空间中。 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. 您最好删除该匿名名称空间。

Can't you befriend your constructor? 你不能和你的构造函数做朋友吗?

You can as shown below 您可以如下图所示

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(){
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM