C++ 友谊和接口

C++ 友谊和接口,c++,C++,我在使用苹果的Clang7.0和下面的友谊代码(使用C++11标准)时出现编译错误。我想知道它到底出了什么问题,因为它似乎对我有效。我正在描述设置和我遇到的错误: MyInterface namespace namespace1 { class MyInterface { friend class MyClass; public: virtual void some_method(void) = 0; ... private: type some_attribute;

我在使用苹果的Clang7.0和下面的友谊代码(使用C++11标准)时出现编译错误。我想知道它到底出了什么问题,因为它似乎对我有效。我正在描述设置和我遇到的错误:

MyInterface

namespace namespace1
{

class MyInterface
{
friend class MyClass;
public:
    virtual void some_method(void) = 0;
    ...
private:
    type some_attribute;   
    ...
}

}
MyClass::MyMethod实现

namespace namespace2
{

void MyClass::MyMethod(MyInterface* MyConcrete)
{
    ...
    // MyConcrete implements MyInterface
    if(MyConcrete->some_attribute == some_value) // Error*
    {
       ...
    }
    ...
}

}
错误

我真的希望
MyClass
能够访问
MyConcrete
(实现了
MyInterface
)中的
某些属性,而不考虑类访问修饰符。为什么会发生这种错误,有什么线索吗?有什么建议吗


谢谢大家!

好友类MyClass::namespace1::MyInterface
的上下文中,code>指的是类
::namespace1::MyClass
,它与
::namespace2::MyClass
不同。(这就是名称空间的全部意义,对吗?)

将好友声明更改为如下所示:

friend class ::namespace2::MyClass;
请注意,这要求类型
::namespace2::MyClass
已经声明,因此您需要向前声明它(
namespace2{class MyClass;}
),或者需要确保在定义
::namespace1::MyInterface
之前包含该定义


(请参阅。)

MyClass位于
名称空间2
中。因此,您需要使用:

friend class namespace2::MyClass;
在定义
MyInterface
之前,您可能还需要使用
MyClass
的正向偏差

下面是一个编译的示例:

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

您可以运行它。

我无法编译您的完整示例。它似乎缺少一个主函数。@ChristopherPisz最好检查一下编译器。在链接之前很久,它就应该被误用
绊倒。界面中的友谊完全违背了界面的用途。坏主意!
// 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()
{
}