MrNexeon
@MrNexeon

Как скопировать объект внутри указателя производного класса?

Допустим, существует класс Base и производный от него класс Derived : public Base

Как скопировать объект d на который указывает указатель *b, если тип производного класса Derived НЕ известен на этапе компиляции?

Derived d;

Base *b = &d;

Base *copy = copy_of(b)?


Скопировать сам указатель не вариант, т.к. они оба будут указывать на одну и ту же область памяти. Возможно ответ кроется в копировании этой самой области памяти изощренным способом?
  • Вопрос задан
  • 358 просмотров
Решения вопроса 1
@MiiNiPaa
Есть два каноничных подхода.
Первый — создать виртуальную функцию clone, которую должны переопределить производные классы:
class Base
{
  pubic:
    virtual Base* clone() const = 0;
};

class Derived: public Base
{
  public:
    virtual Base* clone() const override
    {
        return new Derived(*this);
    }
};


Второй — использовать CRTP чтобы наследовать Base:
class Base
{
  pubic:
    virtual Base* clone() const = 0;
};

template <typename T>
struct BaseHelper: Base
{
  virtual Base* clone() const override
  {
    return new T(static_cast<const T&>(*this));
  }
}

class Derived: public BaseHelper<Derived>
{
};
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Daniro_San
@Daniro_San
Программист
Поделюсь с вами кусочком своего проекта, передо мной уже вставала похожая проблема, за исключением того, что работал я с указателем void*, хранящим любой тип.

Думаю то, что void* нужно исправить на указатель на ваш интерфейс вы догадаетесь.

namespace Typification
{
    // Универсальный тип
    struct Type
    {
        std::string Id;
        std::function<void(void *)> Free;
        std::function<void *(void *)> Copy;
        std::function<bool(void *, void *)> Equall;
    };

    // Шаблонная функция возвращает тип
    template <typename T> Type GetType()
    {
        return
        { 
            typeid(T).name(), 
            [](void *pointer) -> void { delete static_cast<T *>(pointer); },
            [](void *pointer) -> void *{ return new T(*static_cast<T *>(pointer)); },
            [](void *a, void *b) -> bool { return *static_cast<T *>(a) == *static_cast<T *>(b); }
        };
    }
}

// Просто набросок идеи
struct Obj {
    Typification::Type _type;
    void *_value;
};
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы