Итак, у меня есть то, что я считаю довольно распространенной проблемой C++ с участием объекта . Проблемный домен таков: анимированный gif может иметь много кадров , а рисование кадра зависит от контекста других фреймов Gif.Копирование конструкторов для классов с взаимной ссылкой/циклической зависимостью
Так у меня есть эта модель (очень упрощенная на этот вопрос, но должен иллюстрировать):
class Gif {
std::vector<Frame> _frames;
// Makes Frame objects from file and puts them in _frames
Gif(const char* file){...};
// For clarity, works and copies the _frames member
Gif(const Gif& other) = default;
};
class Frame {
Frame(...){
// Make a frame object
}
void draw(const Gif& context){
// draws self considering context's other frames
}
};
Это работает, но для простоты и избегать рисований Frame
в неправильного контекста, я хочу метод draw
не принимает аргумент context
. Так я думал о создании Frames с опорным элементом _context
const
:
class Frame {
const Gif& _context;
// Make a frame object
Frame(const Gif& context) _context(context){...}
// Explicit default copy-constructor, for clarity. Breaks horribly
// when called from Gif's copy constructor, since the new Frame will
// reference the wrong context, which might be deleted.
Frame(const& Frame other) = default;
void draw(){
// draws self considering _context's other frames
}
};
компилируется, но перерывы ужасно при копировании Gif
с. Объекты Frame
новых Gif
являются копиями в порядке, но они ссылаются на неверный контекст , который уже был удален.
я считать, что константные члены ссылки, вероятно, плохая идея для объектов, которые вы собираетесь копировать ... Должен ли я использовать указатель и явно сбросить его для новых Frame
с в теле пользовательских Gif
" s конструктор копирования?
Если да, то какой вид указателя (raw/smart)? Разве нет хорошего метода C++ 11 для создания это происходит «автоматически»?
Или я должен нарушать циклическую зависимость и как?
EDIT (спасибо KillianDS): Чтобы быть ясным, вы начинаете с gif1 с некоторых кадров (frame1_1, frame1_2, ...), которые указывают на gif1, и теперь вы хотите скопировать gif1 в gif2 с скопированными кадрами (frame2_1, frame2_2, ...), но это указывает на gif2?
Чтобы быть ясным, вы начинаете с 'gif1' с некоторыми кадрами (' frame1_1, frame1_2, ... '), которые указывают на' gif1' и теперь вы хотите, чтобы скопировать '' gif1' в gif2' с скопированные кадры ('frame2_1, frame2_2, ...'), но это указывает на 'gif2'? – KillianDS
yes @KillianDS, точно –
Кажется, пользователи класса Gif могут получить доступ к объекту (ссылкам) класса 'Frame'. Почему бы не заставить 'Gif' вместо этого публиковать какой-то тип указателя' FramePointer', который содержит 'Gif const * context' и' Frame * frame'? – dyp