2010-02-23 2 views
2

У меня есть объект ATL COM, который должен выставлять коллекцию других COM-объектов, поэтому клиенты могут узнать, сколько объектов находится в коллекции (через простое свойство Count, которое я могу предоставить) и доступ объекты, используя свой индекс. Этот набор объектов является динамическим - счет не фиксирован - и я не знаю, сколько будет, когда будет сконструирован мой основной (родительский) объект (поэтому я не могу создать эти объекты в моем FinalConstruct, например). Объекты, которые я хочу открыть, имеют свойства только для чтения.Динамический массив COM-объектов

Что я хочу сделать, так или иначе создать std::vector этих объектов при первой необходимости. Я хочу использовать ATL smart COM-указатели, где это возможно, поэтому мне не нужно вручную управлять подсчетами ссылок и т. Д., Но я не уверен, должен ли я использовать CComPtr, «CComQIPtr» и т. Д.

Предполагая объекты Я хочу вернуться, называется IChild, я надеялся, что я мог бы сделать что-то вроде этого:

std::vector<CComPtr<IChild> > children; 
... 
CComPtr<IChild> child; 
// Somehow instantiate an IChild? 
... 
children.push_back(child); 

STDMETHODIMP Parent::GetAt(LONG index, IChild** pRet) 
{ 
    *pRet = children[index]; 
} 

Если у кого есть какие-либо указатели о том, как я могу добиться этого, я был бы очень радушно. Существует excellent article on exposing a static object, но я ничего не могу найти по конкретной проблеме.

ответ

6

Да, std::vector< CComPtr<IChild> > - это способ сделать это - вы получите динамический массив IChild*, который управляет временем жизни IChild -удаленных объектов. Как только вы захотите преобразовать IChild* в производный интерфейс, вам нужно будет использовать QueryInterface() так же, как вы бы использовали dynamic_cast с объектами C++.

Нет смысла использовать CComQIPtr для массива. Основное использование CComQIPtr - это удобный способ вызвать QueryInterface() на указатель на объект, который может реализовать интересующий интерфейс. Вместо вызова QueryInterface() и проверки результата вы вызываете конструктор CComQIPtr и проверяете, содержит ли результирующий объект ненулевой указатель. Вы можете использовать CComQIPtr в коде, который использует ваш массив, но нет смысла использовать его для самого массива.

+2

На самом деле, с MSVS2010 он должен быть 'std :: vector >>' из-за неудачного оператора и перегрузки: http://blogs.msdn.com/b/vcblog/archive/2009 /05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx – mcmcc

+0

Хотя CAdapt не требуется в C++ 11: http://stackoverflow.com/questions/24285016/ do-vectors-of-ccomptr-still-need-cadapt –

+0

Можно ли использовать 'std :: vector'' 'ATL :: CComObject''? –

2

CComPtr<...> предполагает, что вы назначаете ему совместимый интерфейс. CComQIPtr<...> звонит IUnknown::QueryInterface, чтобы получить нужный интерфейс. Вот почему в качестве параметра шаблона требуется дополнительно GUID.

Для ваших целей вы должны пойти с CComPtr, так как вы знаете, что вы всегда будете инициализировать записи с помощью IChild.

Смежные вопросы