shared_ptr возвращает интерфейс - PullRequest
3 голосов
/ 13 декабря 2010

Так что я хакуюсь над своим кодом, пытаясь превратить его в какой-нибудь полуприличный код C ++ 0x, используя GCC 4.5 ..

shared_ptr<IEngineLayer*> createEngineLayer(void)
{
    try
    {
        CEngineLayer* engine = new CEngineLayer;
        IEngineLayer* interface = dynamic_cast<IEngineLayer*>(engine);

        return shared_ptr<IEngineLayer*>(interface);
    }
    catch(std::bad_alloc&)
    {
        // Unable to allocate enough memory for the engine layer.
        return shared_ptr<IEngineLayer*>();
    }
}

И я получаю это ..

shared_ptr_base.h: 545: 65: ошибка: невозможно преобразовать «DEngine :: IEngineLayer *» в «DEngine :: IEngineLayer **» при инициализации

Как я могу это исправить?

(Также, как примечание, будет ли shared_ptr уничтожать как интерфейс, так и CEngineLayer, когда его больше никто не использует?)

Ответы [ 3 ]

4 голосов
/ 13 декабря 2010

A shared_ptr<T> моделирует указатель на T, shared_ptr<T *> моделирует указатель на T.

Предполагая, что CEngineLayer является IEngineLayer, вы можете изменить свой код на:

shared_ptr<IEngineLayer> createEngineLayer()
{
    try
    {
        return shared_ptr<IEngineLayer>(new CEngineLayer);
    }
    catch(const std::bad_alloc&)
    {
        // Unable to allocate enough memory for the engine layer.
        return shared_ptr<IEngineLayer>();
    }
}

Также обратите внимание, что преобразование «производное в базовое» не требует явного преобразования: если CEngineLayer публично наследует от IEngineLayer, указатель на CEngineLayer может быть неявно преобразован в указатель на IEngineLayer.

Также, как примечание, будет shared_ptr уничтожить как интерфейс, так и CEngineLayer, когда никто не использует его больше?

Существует один объект с типом CEngineLayer, который, если деструктор в IEngineLayer является виртуальным (и должен быть), будет корректно уничтожен, когда счетчик ссылок достигнет 0.

2 голосов
/ 13 декабря 2010

Вместо этого верните shared_ptr<IEngineLayer>.

Также не требуется приведение:

shared_ptr<IEngineLayer> createEngineLayer()
{
    try
    {
        CEngineLayer* engine = new CEngineLayer;

        return shared_ptr<IEngineLayer>(engine);
    }
    catch(std::bad_alloc&)
    {
        // Unable to allocate enough memory for the engine layer.
        return shared_ptr<IEngineLayer>();
    }
}
0 голосов
/ 03 сентября 2015

Вы также можете использовать make_shared, который с точки зрения производительности лучше:

std::shared_ptr<IEngineLayer> createEngineLayer(void)
{
    return std::make_shared<CEngineLayer>();
}

Также может быть, что следующий код создает утечку памяти:

std::shared_ptr<IEngineLayer> createEngineLayer(void)
{
    IEngineLayer* pInterface = new CEngineLayer;

    return std::shared_ptr<IEngineLayer>(pInterface);
}

В этом случаеshared_ptr удаляет IEngineLayer, а не CEngineLayer

...