使用未命名的命名空间在API中重新定义友元类并访问私有成员?

时间:2014-11-08 08:31:36

标签: c++ friend

我试图访问某个类的私有成员,这些成员是我无法更改的API的一部分。

清单1: api.h

namespace api {
    class Bar;

    class Foo {
    public:
        const int& getSecret() const { return secretValue; }
    private:
        int secretValue;
        friend class Bar;
    };
}

清单2: program.cpp

#include <iostream>
#include "api.h"

namespace {
    class api::Bar {
        public:
            void touchFooSecretly(api::Foo& f) { f.secretValue = 42; }
    };
}

int main() 
{
    api::Foo f;
    api::Bar b;

    b.touchFooSecretly(f);

    std::cout << f.getSecret() << std::endl; // 42 (Solaris)
    return 0;
}

这在Oracle Solaris Studio 12.3中编译(并运行)很好,但是clang和g ++(可以理解)有问题:

program.cpp:5:13: error: cannot define or redeclare 'Bar' here because namespace '' does not enclose namespace 'api'

为了提高效率,目前正在使用此黑客,并且熟悉课程如何在内部运作。有没有办法在clang中实现类似的技巧,以便我可以单独为我的翻译单元更改朋友类的含义?

或者,如果不这样做,任何让我访问我无法修改声明的类中的私有成员的技巧将不胜感激!

1 个答案:

答案 0 :(得分:1)

如问题的帖子所述,我不知道如何修复此命名空间问题。但是,根据作者的要求,any trick that lets me access a private member in a class where I cannot modify the declarations would be appreciated! ......这是我的诀窍:

#define private public
#include "api.h"
#undef private

那太糟糕了,但如果你知道自己在做什么,这将使所有私人成员在&#34; api.h&#34; (+可能在文件中声明的所有其他类包括&#34; api.h&#34;)是公开的!