友谊和接口

时间:2017-06-05 18:19:01

标签: c++

我使用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_attributeMyConcrete(实现MyInterface),无论类访问修饰符如何。任何线索为什么会发生这种错误?有什么建议吗?

谢谢!

2 个答案:

答案 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