我使用Apple的Clang 7.0和以下友谊代码使用C ++ 11标准时出现编译错误。我不知道它有什么问题,因为它似乎对我有用。我正在描述设置和我遇到的错误:
MyInterface的
namespace namespace1
{
class MyInterface
{
friend class MyClass;
public:
virtual void some_method(void) = 0;
...
private:
type some_attribute;
...
}
}
MyClass :: MyMethod Implementation
namespace namespace2
{
void MyClass::MyMethod(MyInterface* MyConcrete)
{
...
// MyConcrete implements MyInterface
if(MyConcrete->some_attribute == some_value) // Error*
{
...
}
...
}
}
错误
error: 'some_attribute' is a private member of 'namespace1::MyInterface'
我真的希望MyClass
能够访问some_attribute
中MyConcrete
(实现MyInterface
),无论类访问修饰符如何。任何线索为什么会发生这种错误?有什么建议吗?
谢谢!
答案 0 :(得分:1)
friend class MyClass;
上下文中的 ::namespace1::MyInterface
引用了::namespace1::MyClass
类,它与::namespace2::MyClass
不同。 (这就是命名空间的重点,对吗?)
将好友声明更改为:
friend class ::namespace2::MyClass;
请注意,这要求已声明类型::namespace2::MyClass
,因此您需要向前声明它(namespace namespace2 { class MyClass; }
),或者您需要确保在此之前包含该定义::namespace1::MyInterface
的定义。
(见this demo。)
答案 1 :(得分:1)
MyClass在namespace2
。所以你需要使用:
friend class namespace2::MyClass;
在定义MyClass
之前,您可能还需要使用MyInterface
的前向声明。
这是一个编译的例子:
// forward decleration
namespace namespace2
{
class MyClass;
}
namespace namespace1
{
class MyInterface
{
friend class namespace2::MyClass; // added missing namespace
public:
virtual void some_method(void) = 0;
private:
int some_attribute;
};
}
namespace namespace2
{
class MyClass
{
void MyMethod(namespace1::MyInterface* MyConcrete)
{
if(MyConcrete->some_attribute == 1)
{
}
}
};
}
int main()
{
}
您可以运行here。