Еще одна проблема при программировании агрегирования может возникнуть, когда необходимо связать между собой внутренний и внешний объекты. Для того чтобы организовать связь внутреннего объекта с внешним, нужно вызвать QueryInterface посредством управляющего IUnknown. Однако этот запрос QueryInterface вызовет AddRef через результирующий указатель, который имеет обыкновение без спросу обрабатывать внешний объект с помощью AddRef. Если бы внутренний объект хранил этот указатель в качестве элемента данных, то возник бы цикл, поскольку внутренний объект уже неявно обработал внешний объект с помощью AddRef. Это означает, что внутренний объект должен избрать одну из двух стратегий. Внутренний объект может получать и освобождать указатель по потребности, храня его ровно столько времени, сколько это необходимо:
STDMETHODIMP Inner::MethodX(void) { ITruck *pTruck = 0; // outer object will be AddRefed after this call... // после этого вызова внешний объект будет обработан // с помощью AddRef... HRESULT hr = m_pUnkOuter->QueryInterface(IID_ITruck, (void**)&pTruck); if (SUCCEEDED(hr)) { pTruck->ShiftGears(); pTruck->HaulDirt(); // release reference to outer object // освобождаем ссылку на внешний объект pTruck->Release(); } }
Второй способ заключается в том, чтобы получить указатель один раз во время инициализации и освободить соответствующий внешний объект немедленно после получения.