Указатели не могут сохраняться непосредственно в файле, поскольку они указывают на абсолютные адреса. Чтобы решить эту проблему, я написал шаблон relative_ptr
, который содержит смещение вместо абсолютного адреса.
Исходя из того факта, что только тривиально скопируемые типы могут быть безопасно скопированы поэтапно, я сделал предположение, что этот тип должен быть тривиально скопируемым, чтобы быть надежно сохраненным в файле с отображением памяти и извлеченным позже.
Это ограничение оказалось немного проблематичным, потому что созданный компилятором конструктор копий не ведет себя значимым образом. Я не нашел ничего, что запрещало бы мне дефолтировать конструктор копирования и сделать его закрытым, поэтому я сделал его конфиденциальным, чтобы избежать случайных копий, которые приведут к поведению undefined.
Позже я нашел boost::interprocess::offset_ptr
, создание которого было обусловлено одними и теми же потребностями. Однако оказывается, что offset_ptr
не является тривиально-скопируемым, потому что он реализует свой собственный собственный конструктор копирования.
Является ли мое предположение, что интеллектуальный указатель должен быть тривиально скопируемым, чтобы быть безопасным?
Если нет такого ограничения, я задаюсь вопросом, могу ли я смело делать следующее. Если нет, то каковы требования, которые должен выполнять тип для использования в описанном выше сценарии?
struct base {
int x;
virtual void f() = 0;
virtual ~base() {} // virtual members!
};
struct derived : virtual base {
int x;
void f() { std::cout << x; }
};
using namespace boost::interprocess;
void persist() {
file_mapping file("blah");
mapped_region region(file, read_write, 128, sizeof(derived));
// create object on a memory-mapped file
derived* d = new (region.get_address()) derived();
d.x = 42;
d->f();
region.flush();
}
void retrieve() {
file_mapping file("blah");
mapped_region region(file, read_write, 128, sizeof(derived));
derived* d = region.get_address();
d->f();
}
int main() {
persist();
retrieve();
}
Спасибо всем тем, кто предоставил альтернативы. Маловероятно, что в ближайшее время я буду использовать что-то еще, потому что, как я объяснил, у меня уже есть рабочее решение. И, как вы можете видеть из использования вопросительных знаков выше, мне действительно интересно узнать, почему Boost может уйти без тривиально-скопируемого типа и как далеко вы можете с ним справиться: совершенно очевидно, что классы с виртуальными членами не будут работа, но , где вы рисуете линию?