Использование безымянного пространства имен для переопределения класса друга в API и доступа к закрытым членам?

0

Я пытаюсь получить доступ к некоторым частным членам класса, которые являются частью 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, чтобы я мог изменить значение класса friend только для моей единицы перевода?

Или, в противном случае, любой трюк, который позволяет мне получить доступ к закрытому члену в классе, где я не могу изменить объявления, будет оценен по достоинству!

  • 2
    Итак, вы хотите иметь несколько разных определений Bar во всей программе? Если это так, даже если вам удастся скомпилировать его, поведение будет неопределенным.
  • 0
    Мое подразделение перевода будет иметь мое определение Bar, а остальная часть приложения останется неизменной (так как она уже скомпилирована и связана). Я думаю, что это четко определено, но, возможно, я ошибаюсь.
Показать ещё 4 комментария
Теги:
friend

1 ответ

1
Лучший ответ

Как прокомментировано в вопросе, я не знаю, как исправить эту проблему с пространством имен. Но, по просьбе автора, any trick that lets me access a private member in a class where я cannot modify the declarations would be appreciated!... вот мой трюк:

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

Это ужасно, но если вы знаете, что делаете, это приведет к тому, что все частные члены будут объявлены в классах "api.h" (+ все остальные классы, которые, возможно, объявлены в файлах, включают в себя "api.h"), являются общедоступными!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню