Можно ли использовать слабые ссылки в качестве переменных экземпляра в Windows RT/8?

Я реализую дерево в одном из своих проектов. Каждый узел содержит вектор с нулем или более дочерними узлами. Каждый узел также содержит ссылку на своего родителя (родительской ссылкой корня является nullptr). Вот пример определения класса:

ref class TreeNode {
    ...

    TreeNode^ _parentNode;
    Platform::Collections::Vector<TreeNode^>^ _childNodes;
}

Во-первых, вызовет ли это утечку памяти? Я предполагаю, что это сильные ссылки в обоих направлениях, и поэтому количество ссылок на объекты останется выше нуля.

Я видел примеры Platform::WeakReference, но никогда в качестве переменных экземпляра. Это возможно? Как будет выглядеть синтаксис?


person Brent Traut    schedule 25.10.2012    source источник


Ответы (1)


Да, ваш код в том виде, в каком он написан, приведет к циклу подсчета ссылок и утечке вашего дерева.

Platform::WeakReference может быть переменной экземпляра, но, поскольку это тип только для C++, он не может быть на общедоступной поверхности TreeNode. Всякий раз, когда вы хотите получить доступ к слабой ссылке, вы должны вызвать .Resolve<TreeNode>() для слабой ссылки, чтобы создать сильную ссылку. Вы можете рассмотреть возможность использования свойства для слабой ссылки:

ref class TreeNode sealed {
public:
    property TreeNode^ Parent {
        TreeNode^ get(){
            return _parentNode.Resolve<TreeNode>();
        }

        void set(TreeNode^ tn) {
            _parentNode = tn;
        }
    };

private:
    Platform::WeakReference _parentNode;
    Platform::Collections::Vector<TreeNode^>^ _childNodes;
};
person Andy Rich    schedule 25.10.2012
comment
Точно! Спасибо за пример. - person Brent Traut; 26.10.2012
comment
О, одно быстрое исправление в вашем коде. При разрешении WeakReference вы не указываете ^ в шаблоне. Пятая строка должна читаться как return _parentNode.Resolve<TreeNode>(); - person Brent Traut; 26.10.2012
comment
Ах - хороший момент. Я обновил пример кода, чтобы удалить эти шляпы. Это то, что я получаю за написание кода, не пытаясь его скомпилировать... :) - person Andy Rich; 06.11.2012
comment
С тех пор я узнал, что Platform::WeakReference также переопределяет оператор = (равно). Вместо установки _parentNode = Platform::WeakReference(tn); можно просто написать _parentNode = tn;. - person Brent Traut; 06.11.2012