PavelK
@PavelK

Как создать новый экземпляр класса переменной?

Приветствую.
Нужно создать новый экземпляр класса переменной.
Пробую так:
MyClass * a = new MyClass();

BaseClassOfMyClass * b =  a;
b->makecopy();

void BaseClassOfMyClass::makecopy()
{
   BaseClassOfMyClass * C = new std::remove_reference<decltype(*this)>::type();
}

Но создаётся экземпляр класса BaseClassOfMyClass, хотя я ожидал MyClass.

Подскажите, можно ли вообще реализовать такое?
  • Вопрос задан
  • 231 просмотр
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
1. В Си++ нет такого понятия, как виртуальный конструктор. А виртуальный конструктор копирования — я вообще не понимаю…
2. В makecopy вы допустили ошибку — переменная никуда не девается и тупо занимает память.
3. Чтобы отдать указатель на переменную и сказать: «сам уничтожай, когда хочешь»,— есть стандартный тип unique_ptr. Но для ковариантности по unique_ptr нужны две функции: одна виртуальная и возвращает простой указатель, другая отдаёт конкретный u_p.

Для простоты предполагаю, что все классы неабстрактные, и виртуальная vclone имеет права доступа public, а не protected.
#include <iostream>
#include <memory>

#define IMPLEMENT_CLONE_1(Class, Keyword) \
    virtual Class* vclone() const Keyword { return new Class(*this); }  \
    auto clone() const { return std::unique_ptr<Class>{vclone()}; }

#define IMPLEMENT_CLONE(Class)  IMPLEMENT_CLONE_1(Class, override)

class BaseClass {
public:
  IMPLEMENT_CLONE_1(BaseClass, )
  virtual ~BaseClass() = default;
};

class MyClass : public BaseClass {
public:
  IMPLEMENT_CLONE(MyClass)
  void print() const { std::cout << "I'm a MyClass!" << std::endl; }
};

int main()
{
  auto a = std::make_unique<MyClass>();
  auto b = a->clone();
  b->print();
  return 0;
}


Есть ещё вот такая хрѣнь. Я уж не знаю, что лучше: сóрок пя́ток или пятóк сорóк прямое преобразование указателей или препроцессор.

#include <iostream>
#include <memory>

class BaseClass {
public:
    auto clone() const { return std::unique_ptr<BaseClass>{ vclone() }; }
protected:
    virtual BaseClass* vclone() const { return new BaseClass(*this); }
};

template <class Super, class This>
class CloneImpl : public Super
{
public:
    auto clone() const { return std::unique_ptr<This>{ static_cast<This*>(vclone()) }; }
protected:
    CloneImpl* vclone() const override { return new This(*static_cast<const This*>(this)); }
};

class MyClass : public CloneImpl<BaseClass, MyClass> {
public:
  void print() const { std::cout << "I'm a MyClass!" << std::endl; }
};

int main()
{
    auto a = std::make_unique<MyClass>();
    auto b = a->clone();
    b->print();
    return 0;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы