Использование безымянного пространства имен для переопределения класса друга в API и доступа к закрытым членам?
Я пытаюсь получить доступ к некоторым закрытым членам класса, который является частью 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 ответ
Как прокомментировано в посте вопроса, я не знаю, как решить эту проблему с пространством имен. Но, по просьбе автора, 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
Это ужасно, но если вы знаете, что делаете, это сделает общедоступными все закрытые члены, объявленные в классах "api.h" (+ все остальные классы, возможно, объявленные в файлах, включая "api.h")!