Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using std::unique_ptr for managing COM objects

I'm trying to use smart pointers to hold COM objects in my class while avoiding ComPtr. Is it possible to use unique_ptr for this purpose?

I'm quite new to smart pointers and so far I'm a bit confused. Please consider the following simplified code:

class Texture
{
private:
    struct ComDeleter
    {
        operator() (IUnknown* p)
        {
            p.Release();
            delete p;
        }
    }

    ID3D11Texture* m_dumbTexture;
    std::unique_ptr<ID3D11Texture, ComDeleter> m_smartTexture;

public:
    ID3D11Texture* getDumbTexture() const { return m_dumbTexture; }
    ID3D11Texture* getSmartTexture() const { return m_smartTexture.get(); } // what to return here?
}

Texture::Texture() :
    dumbTexture  (NULL),
    smartTexture (nullptr)
{
}

Texture::init()
{
    D3DX11CreateTexture(&m_dumbTexture);
    D3DX11CreateTexture(&m_smartTexture.get());  // error: '&' requires r-value
}

So my problems are: what should the getter return (raw pointer or unique_ptr instance) and how can I pass the unique_ptr to function which creates the resource?

like image 447
jaho Avatar asked Feb 17 '14 03:02

jaho


People also ask

When should we use unique_ptr?

When to use unique_ptr? Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.

What does unique_ptr get do?

unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.

Does unique_ptr delete automatically?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.

What is the class template unique_ptr used for?

The unique_ptr class supersedes auto_ptr , and can be used as an element of C++ Standard Library containers. Use the make_unique helper function to efficiently create new instances of unique_ptr .


2 Answers

I'm trying to use smart pointers to hold COM objects in my class while avoiding ComPtr.

The solution is to use ComPtr. unique_ptr is a poor substitute for ComPtr if you're working with COM objects.

ComPtr provides specialized functionality for working with COM objects and IUnknown. For example, it has built in support for safe interface querying (via the As member function). It is also usable with out parameters, which are common in COM (via the GetAddressOf functions).

like image 90
James McNellis Avatar answered Nov 03 '22 21:11

James McNellis


If you really want to partially reinvent the wheel, you should use intrusive_ptr. Implement the incrementation/decrementation methods for IUnknown with calling AddRef() and Release() and it should work.

like image 35
Medinoc Avatar answered Nov 03 '22 21:11

Medinoc