I have two vectors. I register derived classes in one vector, then want to make copies and copy them over to the other vector. I am trying to do this to avoid base class slicing, but be able to have "templates" of classes that I use to spawn new objects that I can mutate from those.
How do I clone an object pointed to by unique_ptr
and have a new unique_ptr
that I can store in a vector
?
The idea shown below is that I could have multiple copies of the class in active
, while still having the original object in available
. Or, is there a better architecture for trying to make copies of a derived class for storage?
#include <iostream>
#include <memory>
#include <vector>
class BaseClass {
virtual void doSomething(){}
};
class DerivedClass1: public BaseClass {
public:
float myVar1;
void doSomething() override { std::cout << "1"; }
};
class DerivedClass2: public BaseClass {
public:
int myVar2;
void doSomething() override { std::cout << "2"; }
};
std::vector<std::unique_ptr<BaseClass>> available;
std::vector<std::unique_ptr<BaseClass>> active;
void registerClass( std::unique_ptr<BaseClass> newAvailable ) {
available.push_back(std::move(newAvailable));
}
void makeActive() {
for( auto &toMakeActive : available ) {
// todo: ?? // active.push_back( available->clone() );
}
}
int main() {
std::unique_ptr<DerivedClass1> derived1 = std::make_unique<DerivedClass1>();
std::unique_ptr<DerivedClass2> derived2 = std::make_unique<DerivedClass2>();
registerClass( std::move( derived1 ) );
registerClass( std::move( derived2 ) );
makeActive();
makeActive();
return 0;
}
How do I clone an object pointed to by
unique_ptr
and have a newunique_ptr
that I can store in avector
?
C++ has no facility to handle this automatically, you have to implement it manually in each derived class, eg:
#include <iostream>
#include <memory>
#include <vector>
class BaseClass {
virtual void doSomething(){}
virtual std::unique_ptr<BaseClass> clone() = 0;
};
class DerivedClass1: public BaseClass {
public:
float myVar1;
void doSomething() override { std::cout << "1"; }
std::unique_ptr<BaseClass> clone() override { return std::make_unique<DerivedClass1>(*this); }
};
class DerivedClass2: public BaseClass {
public:
int myVar2;
void doSomething() override { std::cout << "2"; }
std::unique_ptr<BaseClass> clone() override { return std::make_unique<DerivedClass2>(*this); }
};
std::vector<std::unique_ptr<BaseClass>> available;
std::vector<std::unique_ptr<BaseClass>> active;
void registerClass( std::unique_ptr<BaseClass> newAvailable ) {
available.push_back(std::move(newAvailable));
}
/* alternatively:
template<class T>
void registerClass() {
available.push_back(std::make_unique<T>());
}
*/
void makeActive() {
for( auto &toMakeActive : available ) {
active.push_back( available->clone() );
}
}
int main() {
registerClass( std::make_unique<DerivedClass1>() );
registerClass( std::make_unique<DerivedClass2>() );
/* alternatively:
registerClass<DerivedClass1>();
registerClass<DerivedClass2>();
*/
makeActive();
makeActive();
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.