Самый простой способ реализовать глубокую копию, которая может включать круговые ссылки, если вы хотите, чтобы она была толерантна к изменениям структуры позже, заключалась бы в использовании IdentityHashMap
и IdentityHashSet
(из здесь [/ д0]). Если вы хотите скопировать:
IdentityHashMap
, чтобы сопоставить исходные объекты с их клонами. IdentityHashSet
для отслеживания всех объектов, которые в настоящее время находятся в процессе клонирования, но еще не закончены. IdentityHashMap
, чтобы узнать, уже ли вы клонировали этот бит. Если у вас есть, верните копию, которую вы найдете в IdentityHashMap
. IdentityHashSet
, чтобы увидеть, находитесь ли вы в середине клонирования объекта, который вы сейчас достигли (из-за круговая ссылка). Если у вас есть, просто установите его на null
и продолжайте движение. IdentityHashSet
, рекурсивно глубоко клонируйте его, а затем, когда вы закончите рекурсивный вызов, добавьте пару source / clone в IdentityHashMap
и удалите его из IdentityHashSet
. null
, которые вы оставили, потому что вы столкнулись с круглой ссылкой. Вы можете одновременно просматривать график источника и места назначения. Всякий раз, когда вы находите объект в исходном графе, найдите его в своем IdentityHashMap
и узнайте, на что он должен сопоставляться. Если он существует в IdentityHashMap
, и если он на данный момент null
на графике назначения, вы можете установить ссылку назначения на клон, который вы найдете в IdentityHashMap
. Это позволит вам не клонировать одну и ту же часть графика дважды, но всегда заканчивается тем же ссылкой, когда есть объект, который дважды появляется на вашем графике. Это также означает, что циклические ссылки не вызывают бесконечной рекурсии.
Точка использования версий Identity
заключается в том, что если два объекта на вашем графике совпадают, как определено .equals()
, но разные экземпляры, определенные ==
, тогда HashSet
и HashMap
будут идентифицировать эти два, и вы в конечном итоге соедините вещи вместе, которые не должны соединяться. Варианты Identity
будут обрабатывать два экземпляра одинаково, только если они идентичны, то есть то же, что определено ==
.
Если вы хотите сделать все это, но без необходимости его реализации вы могли бы взглянуть на библиотеку глубокого клонирования Java .
У вас должно быть определение любой статической переменной-члена. Это определение должно быть в исходном файле из-за одного правила определения.
Просто добавьте строку:
QFrame* SuperFalcon::fWidget;
в «superfalcon.cpp».
Вы должны инициализировать вашу статическую переменную в superfalcon.cpp:
QFrame* SuperFalcon::fWigdet = nullptr;