C++ C++;在不同名称空间中具有相同名称的好友类

C++ C++;在不同名称空间中具有相同名称的好友类,c++,class,namespaces,c++-cli,friend,C++,Class,Namespaces,C++ Cli,Friend,我在不同的命名空间中有两个同名的类。我无法修改类的名称。 我想向其中一个类添加一个方法,但不允许将其作为公共方法添加。另一个类在C++/CLI中作为ref类编写,需要访问此方法。 我试图使用friend类,但我不知道该如何使用它 标准c++中的dll: namespace X { class A { protected: __declspec(dllexport) void method(); } } C++/CLI中的应用 namesp

我在不同的命名空间中有两个同名的类。我无法修改类的名称。 我想向其中一个类添加一个方法,但不允许将其作为公共方法添加。另一个类在C++/CLI中作为ref类编写,需要访问此方法。 我试图使用friend类,但我不知道该如何使用它

标准c++中的dll:

namespace X
{
    class A
    {
        protected:
        __declspec(dllexport) void method();
    }
}
C++/CLI中的应用

namespace Y
{
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            otherClass.method();
        }
    }
}
我尝试了以下方法: 朋友类Y::A;//编译器错误C2653:Y不是类或命名空间名称

当我声明名称空间Y时,出现错误C2039:“A”:不是“Y”的成员

我不能在命名空间y中添加类A的前向声明,因为类A是用标准C++编译的,在前向声明中,我必须声明它为REF类。< /P> 编译器:VisualStudio2008

有人有主意吗

多谢各位

解决方案(感谢Sorayuki):

#ifdef __cplusplus_cli
    #define CLI_REF_CLASS ref class
#else
    #define CLI_REF_CLASS class
#endif

namespace Y { CLI_REF_CLASS A; }

namespace X
{
    class A
    {
        protected:
        friend CLI_REF_CLASS Y::A;
        __declspec(dllexport) void method();
    }
}

我不确定这种把戏是否被允许

但也许你想看看这种“黑客行为”:

在c++/cli中

namespace Y
{
    class HackA : public X::A {
        public:
        void CallMethod() { method(); }
    };
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            assert(sizeof(HackA) == (X::A));
            HackA* p = (HackA*) &otherClass;
            p->CallMethod();
        }
    };
};
编辑:

#ifdef __cplusplus_cli
    #define CLI_REF_CLASS ref class
#else
    #define CLI_REF_CLASS class
#endif

namespace Y { CLI_REF_CLASS A; }

namespace X
{
    class A
    {
        protected:
        friend CLI_REF_CLASS Y::A;
        __declspec(dllexport) void method();
    }
}
我已经测试过,这可以通过编译

namespace Y { ref class A; };

namespace X
{
    class A
    {
        friend ref class Y::A;
        protected:
        __declspec(dllexport) void method();
    };
};

namespace Y
{
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            otherClass.method();
        }
    };
};

也许您只需要复制X::A的头文件,并通过在名称空间X之前添加一个声明(而不是定义)Y::A来编辑副本,并包含“副本”即可。

我认为这是可行的,但这不是一段好代码。如果没有不同的方式,我必须使用这种黑客攻击,但我不知道是否允许使用它。谢谢,但是这不是用标准的C++编译器编译的。dll不使用.NET。我已经和我的客户谈过了:我可以用你的第一个答案。我知道。所以我建议你复制一个.h,然后修改它,否则dll将无法编译。顺便说一下,您可以定义一个宏MYREF或其他什么,当使用其他编译器编译时,它被定义为nothing,当使用.net编译时,它被定义为“ref”。我已经添加了解决方案。非常感谢。