user37337
user37337

Reputation: 327

C++ friend class with same name in different namespaces

I have two classes with the same name in different namespaces. I cannot modify the names of the classes. I want to add a method to one of the class, but I'm not allowed to add this as a public method. The other class is written in C++/CLI as ref class and needs access to this method. I tried to use friend class but I have no idea how I should use it.

dll in standard c++:

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

application in C++/CLI

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

I've tried the following: friend class Y::A; // compiler error C2653: Y is not a class or namespace name

when I declare the namespace Y I get the error C2039: 'A' : is not a member of 'Y'

I cannot add a forward declaration of class A in namespace Y because class A is compiled with standard C++ and in a forward declaration I have to declare it as ref class.

Compiler: Visual Studio 2008

Does anybody have an idea?

Thank you

Solution (thanks to 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();
    }
}

Upvotes: 0

Views: 1125

Answers (1)

Sorayuki
Sorayuki

Reputation: 266

I'm not sure if this kind of trick is allowed.

but maybe you would like to have a look on this kind of "hacking":

in 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();
        }
    };
};

edit:

I have tested that this could pass the compiling

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();
        }
    };
};

maybe you just need to copy the header file of X::A and edit the copy by adding a declare (not define) Y::A before namespace X. and include the "copy" instead.

Upvotes: 1

Related Questions