J'ai une interface COM avec une méthode qui retourne un objet:Comment mieux initialiser un compteur de référence pour un objet COM non créable?
interface ICreatorInterface {
HRESULT CreateObject(IObjectToCreate**);
};
La clé est que l'appel ICreatorInterface::CreateObject()
est le seul moyen de récupérer un objet qui implémente l'interface IObjectToCreate
.
En C++ je pouvais le faire de cette façon:
HRESULT CCreatorInterfaceImpl::CreateObject(IObjectToCreate** result)
{
//CObjectToCreateImpl constructor sets reference count to 0
CObjectToCreateImpl* newObject = new CObjectToCreateImpl();
HRESULT hr = newObject->QueryInterface(__uuidof(IObjectToCreate), (void**)result);
if(FAILED(hr)) {
delete newObject;
}
return hr;
}
ou cette façon
HRESULT CCreatorInterfaceImpl::CreateObject(IObjectToCreate** result)
{
//CObjectToCreateImpl constructor sets reference count to 1
CObjectToCreateImpl* newObject = new CObjectToCreateImpl();
HRESULT hr = newObject->QueryInterface(__uuidof(IObjectToCreate), (void**)result);
// if QI() failed reference count is still 1 so this will delete the object
newObject->Release();
return hr;
}
La différence est la façon dont le compteur de référence est initialisé et comment la suppression de l'objet est mis en œuvre en cas QueryInterface()
échoue . Depuis que je contrôle complètement à la fois CCreatorInterfaceImpl
et CObjectToCreateImpl
je peux aller de deux façons.
IMO la première variante est plus claire - tout le matériel de comptage de référence est dans un morceau de code. Ai-je supervisé quelque chose? Pourquoi la deuxième approche pourrait-elle être meilleure? Lequel de ce qui précède est meilleur et pourquoi?
Je vois votre point, mais le même comportement peut être réalisé beaucoup plus simple: init refcount avec 0 dans le constructeur et utiliser un pointeur intelligent dans le code en question - il suffit de lier l'objet new'ed à la puce pointeur, alors appelez QI() - ATL :: CComPtr le permet, peut-être que _com_ptr_t le permet aussi. – sharptooth