C++ 交朋友
我试图成为一个类的朋友,以便它能够到达它的私有构造函数 在某个文件中C++ 交朋友,c++,friend,C++,Friend,我试图成为一个类的朋友,以便它能够到达它的私有构造函数 在某个文件中 class B; namespace some_name { class A { public: A() {} private: A (int x) {} friend class ::B; }; } 在其他文件中 #include "some_file" namespace { class B { protected: A* get_a(int x) { return
class B;
namespace some_name {
class A {
public:
A() {}
private:
A (int x) {}
friend class ::B;
};
}
在其他文件中
#include "some_file"
namespace {
class B {
protected:
A* get_a(int x) { return new A(x); }
};
}
编译此代码时,我得到-
错误:“some_name::A::Aint”是私有的
我现在,这是私人的,这就是我和B成为朋友的原因。
我做错了什么?
你不能和你的构装师交朋友吗?
是否存在名称空间问题
感谢您这样做:
namespace {
class B {
protected:
A* get_a(int x) { return new A(x) };
}
}
您没有将B放在根全局名称空间中,而是放在匿名名称空间中
所以B不能通过::B访问
如果您希望B位于根全局命名空间中,只需根本不使用命名空间将其括起来即可。这应该可以达到目的。这样做:
namespace {
class B {
protected:
A* get_a(int x) { return new A(x) };
}
}
您没有将B放在根全局名称空间中,而是放在匿名名称空间中
所以B不能通过::B访问
如果您希望B位于根全局命名空间中,只需根本不使用命名空间将其括起来即可。这应该可以做到这一点。您只转发在全局命名空间中声明的类B并与之建立友谊。不是命名空间中的类B。您需要完全限定B的名称 编辑:谢谢你。
我犯了一个小错误。确实,你遇到问题的原因是因为你错误地声明和引用了B,但我最初的陈述并不完全正确。您需要将B从匿名名称空间中删除—不管怎样,它在头中是没有意义的。您只在全局名称空间中转发声明的类B并与之建立友好关系。不是命名空间中的类B。您需要完全限定B的名称 编辑:谢谢你。
我犯了一个小错误。确实,你遇到问题的原因是因为你错误地声明和引用了B,但我最初的陈述并不完全正确。你需要把B从匿名名称空间中去掉——不管怎样,在头中是没有意义的。问题是你把B称为::B而不是B。这意味着,你告诉编译器B是一个全局名称,但事实上它不是:它在匿名名称空间中。您不必删除匿名名称空间,只是它可能不会执行您期望它执行的操作。因为匿名名称空间位于头中,这意味着名称空间中的内容静态链接到包含头的任何实现文件。这不是很有用,因为你什么都不隐瞒。您还可以删除该匿名名称空间。问题是您将B称为::B而不是B。这意味着,您告诉编译器B是一个全局名称,但实际上不是:它在匿名名称空间中。您不必删除匿名名称空间,只是它可能不会执行您期望它执行的操作。因为匿名名称空间位于头中,这意味着名称空间中的内容静态链接到包含头的任何实现文件。这不是很有用,因为你什么都不隐瞒。您还可以删除该匿名名称空间 你不能和你的构装师交朋友吗 您可以按如下所示进行操作
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(){
}
你不能和你的构装师交朋友吗
您可以按如下所示进行操作
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(){
}
好的,但是如果我无法控制B的位置,而且它必须是匿名名称空间,那么我如何才能使它仍然工作?@izex:这个匿名名称空间的作用就是禁止在匿名名称空间之外引用这种类型。除非将声明移动到同一匿名命名空间中,否则没有办法。这非常有意义。谢谢。@izex:我可以从你的个人资料中看出,你还没有接受任何问题的答案。如果答案满足你的需要,别忘了接受它。欢迎来到SO!那是错误的。这里的匿名名称空间效应完全被它位于头中这一事实所击败。任何包含头的实现文件都将该名称空间的内容静态链接到自身,从而获得匿名名称空间的内容。也就是说,您可以访问B,只需说B而不是::B。好的,但是如果我无法控制B的位置,并且它必须是一个匿名名称空间,那么我如何才能使它仍然工作?@izex:这个匿名名称空间的作用正是禁止在匿名名称空间之外引用此类型。除非将声明移动到同一匿名命名空间中,否则没有办法。这非常有意义。谢谢。@izex:我可以从你的个人资料中看出,你还没有接受任何问题的答案。如果答案满足你的需要,别忘了接受它。欢迎来到SO!那是错误的。这里的匿名名称空间效应完全被它位于头中这一事实所击败。任何包含头的实现文件都将该名称空间的内容静态链接到自身,从而获得匿名名称空间的内容。也就是说,您可以访问B,只需说B而不是::B。B的名称已经完全限定::B,但我猜OP只是意味着一个空的命名空间产生了全局命名空间。B的名称已经完全限定::B,但我猜
OP只是意味着一个空的名称空间将产生一个全局名称空间。要成为其他类的朋友,只需戴上一顶礼帽,戴上一根练习旋转的手杖,穿上几双带有新鲜皮革气味的鞋子。那个眼睛闪闪发光的人走了!人们会发表评论,通过新课程打开新机会的大门。要成为其他课程的朋友,只需戴上一顶礼帽,带上一根练习旋转的手杖,以及一些带有新鲜皮革气味的漂亮鞋子。那个眼睛闪闪发光的人走了!人们会发表评论,用新课程打开新机会的大门。