Как преобразовать raw в смарт-указатель, когда смарт-указатель объявлен в заголовке? - PullRequest
0 голосов
/ 02 мая 2019

В нашем коде мы в основном используем необработанные указатели, и я бы хотел шаг за шагом вводить умные указатели (т.е. без изменения существующих функций).У нас есть фабрика, которая возвращает указатель на созданный объект.Несколько методов в классе используют этот объект, поэтому указатель на созданный объект объявлен как член класса.

std::unique_ptr<IObject> object;

Теперь я хотел бы заменить необработанный указатель умным указателем.

Я обнаружил, что могу передать необработанный указатель в конструктор умного указателя (в моем случае я думаю, что unique_ptr правильный), но поскольку умный указатель объявлен в заголовке, это не работает.Я попытался использовать

object = make_unique<IObject>(CreateObject(1));

, но это дает ошибку компиляции, потому что IObject является абстрактным.Единственное решение, которое я смог найти, - это создать временный unique_ptr и затем использовать move.

//Factory.h
std::unique_ptr<IObject> object; 


//Factory.cpp
IObject* ObjectFactory::CreateObject(int type)
{
   switch( type )
   {
      case 1:
         return new A();
      case 2:
        return new B();
   }
}

//My solution is:
 object = std::move( std::unique_ptr<IObject>(ObjectFactory::CreateObject(1)) );

Мне было интересно, есть ли лучший способ, чем создать временный умный указатель и затем использовать move для передачи права собственности.

1 Ответ

0 голосов
/ 03 мая 2019

Вы можете использовать reset функцию-член уникального указателя, чтобы установить Iobject тип объекта на необработанный указатель с вашей фабрики.

//Factory.h
std::unique_ptr<IObject> object; 


//Factory.cpp
IObject* ObjectFactory::CreateObject(int type)
{
   switch( type )
   {
      case 1:
         return new A();
      case 2:
        return new B();
   }
}

//use reset
object.reset(ObjectFactory::CreateObject(1));

Вот минимальный рабочий пример.

#include <iostream>
#include <memory>

class Abs {
public:
    virtual ~Abs() = 0;
};
Abs::~Abs(){ std::cout << "called\n"; }
class A: public Abs {};
class B: public Abs {};

Abs* Factory(int type)
{
    switch(type)
    {
        case 1:
            new A();
            break;
        case 2:
            new B();
            break;
    }
}
int main()
{
    std::unique_ptr<Abs> obj;
    obj.reset(Factory(1));
    return 0;
}
...