Скопируйте производный класс только с указателем базового класса в C ++ - PullRequest
2 голосов
/ 27 февраля 2020

Я пытаюсь сделать копию производного класса только с указателем базового класса.

Так что, если у меня есть:

class BaseClass; //Abstract class with =0 functions
class LeftClass : BaseClass;
class RightClass : BaseClass;

И у меня есть функция, которая принимает BaseClass как параметр:

void Function(BaseClass* baseClass)

Я хочу сделать копию BaseClass, но я также хочу скопировать расширенную функциональность LeftClass ИЛИ RightClass, но я не знаю, какой один был передан функции - оба возможны.

Итак, у меня есть что-то вроде этого:

//global
vector<BaseClass*> myVector;

void Function(BaseClass* baseClass)
{
   BaseClass* baseClassCopy = new BaseClass(baseClass);
   myVector.push_back(baseClassCopy);
}   

И затем я вызываю функцию с левым или правым классом

int main()
{
   LeftClass leftClass;
   Function(&leftClass);
   LeftClass* ResultOfCopy = myVector.at(0);
}

Этот код не копирует весь левый класс как копию, есть ли способ сделать это, я пропускаю?

Также BaseClass является абстрактным, некоторые функции =0 так что я не могу новый. В противном случае в других классах есть функция копирования.

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Эта проблема обычно решается методом clone().

class BaseClass
{
    virtual BaseClass* clone()            = 0
};

class LeftClass: public BaseClass
{
    virtual LeftClass* clone() override {return new LeftClass(*this);}
};
class RightClass: public BaseClass
{
    virtual RightClass* clone() override {return new RightClass(*this);}
};
class RightRightClass: public RightClass
{
    virtual RightRightClass* clone() override {return new RightRightClass(*this);}
};

Ваша функция теперь легко написать:

void Function(BaseClass* baseClass)
{
   BaseClass* baseClassCopy = !baseClass ? nullptr : baseClass->clone();
   myVector.push_back(baseClassCopy);
}   
2 голосов
/ 27 февраля 2020

Если вы не можете изменить какой-либо из классов для добавления функции клонирования, то вы можете вручную сделать это самостоятельно, используя dynamic_cast, чтобы определить тип времени выполнения и вызвать правильный производный конструктор. Это выглядело бы как

void Function(BaseClass* baseClass)
{
    if (auto ptr = dynamic_cast<LeftClass*>(baseClass))
        myVector.push_back(new LeftClass(*ptr));
    if (auto ptr = dynamic_cast<RightClass*>(baseClass))
        myVector.push_back(new RightClass(*ptr)); 
}  

, и вы можете увидеть, как это работает в этом живом примере

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...