Так как это неправильно понято, я должен уточнить. Все следующие решения не требуют перекомпиляции объекта . Чтобы использовать класс в своем коде, если он скомпилирован в объектный файл, вы должны включить заголовочный файл с объявлением этого класса.
#include <class.h>
ObjectFoo instance;
Возможно (но опасно, если вы не осторожны) изменить заголовок (a) или скопировать заголовок в другое место и включить этот заголовок (b), без перекомпиляции класса сама .
#include <class_fixed.h>
ObjectFoo instance;
Ваш код, в который вы включили новый заголовок, просто подумает , что в объектном файле (который вы не перекомпилировали!) Он найдет реализацию класса, объявленного как в class_fixed.h
. Пока сохраняется класс, объявленный как в class.h
. Если вы измените смещения членов (например, добавьте новых участников) в своем новом заголовке, вы мертвы и код не будет работать должным образом. Но просто изменение доступа работает нормально. Скомпилированный код не знает о доступе, это важно только при компиляции.
Это не всегда вредно. В повседневной жизни вы сталкиваетесь с таким изменением, когда устанавливаете новую версию библиотеки в вашу систему и не перекомпилируете все программы, которые зависят от нее. Но с этим нужно обращаться осторожно
Есть несколько решений.
memcpy()
Не! Не используйте memcpy, поскольку копирование объектов иногда подвергается определенной политике, навязанной разработчиком класса. Например, auto_ptr
s нельзя просто скопировать в память: если вы запечатлите auto_ptr
и запустите деструктор для обоих, вы попытаетесь освободить одну и ту же память два раза, и программа авария.
Измените private:
на public:
в заголовке или с помощью макроса
Если ваша лицензия это позволяет, вы можете решить вашу проблему, отредактировав файл заголовка, который поставляется с реализацией класса . Независимо от того, находится ли исходный код реализации (т.е. cpp-файл класса) под вашим контролем, не имеет значения: достаточно изменить private на public для членов данных (в заголовке) и работает просто отлично, даже если вы получили бинарный единственная библиотека, которая содержит определение класса. (Для функций-членов изменение доступа иногда меняет свое внутреннее имя, но для MSVS и GCC это нормально.)
Добавление новой функции получения
При изменении private
на public
почти всегда все в порядке (если только вы не полагаетесь на определенные проверки во время компиляции, которые должны прервать компиляцию, если в классе есть определенный доступный член), добавление новой функции получения должно выполняться аккуратно. Функция получения должна быть встроенной (и поэтому определена в заголовочном файле класса).
reinterpret_cast
Приведение работает отлично , если вы НЕ приводите указатель на динамический базовый класс (динамическое средство "с виртуальными функциями или базами) ") чей фактический экземпляр на момент приведения может быть получен из класса по конкретному коду.
protected:
И на всякий случай, если вы забыли. C ++ может объявлять члены protected:
, то есть доступные только для классов, производных от заданных. Это может удовлетворить ваши потребности.