I have base class and a lot of classes derived from if. I want to create object copy. Is there a way to deduct real type of object under pointer to base class without dynamic_cast or implementation of createCopy in every derived class?
Something like this:
class Base {
public:
Base(){};
virtual ~Base() = default;
virtual void fun() = 0;
Base *createCopy()
{
return new /*some way to deduct real "this" type */
}
};
class Derived1 : public Base
{
public:
Derived1() : Base(){};
virtual void fun() { /* impl */ };
};
class Derived2 : public Base
{
public:
Derived2() : Base(){};
virtual void fun() { /* impl */ };
};
/* Derived3 - Derived8999 implementation*/
class Derived9000 : public Base
{
public:
Derived9000() : Base(){};
virtual void fun() { /* impl */ };
};
int main()
{
Base *pObj = new Derived9000; // pObj type is Derived9000*
Base *pCopy = pObj->createCopy(); // pCopy type is Derived9000*
}
You can do this in two ways. You can store the type in a middle layer like this:
class Base {
public:
Base(){};
virtual ~Base() = default;
virtual void fun() = 0;
virtual Base *createCopy() = 0;
};
template <typename Type>
class MiddleBase : public Base {
public:
MiddleBase(){};
virtual void fun() = 0;
Base *createCopy() final override
{
return new Type();
}
};
class Derived1 : public MiddleBase<Derived1>
{
public:
Derived1() : MiddleBase(){};
virtual void fun() { /* impl */ };
};
class Derived2 : public MiddleBase<Derived2>
{
public:
Derived2() : MiddleBase(){};
virtual void fun() { /* impl */ };
};
/* Derived3 - Derived8999 implementation*/
class Derived9000 : public MiddleBase<Derived9000>
{
public:
Derived9000() : MiddleBase(){};
virtual void fun() { /* impl */ };
};
int main()
{
Base *pObj = new Derived9000; // pObj type is Derived9000*
Base *pCopy = pObj->createCopy(); // pCopy type is Derived9000*
}
Or IMO a better way you could just let the copy function be overloaded by the specific types and just let each type handle its copy:
class Base {
public:
Base(){};
virtual ~Base() = default;
virtual void fun() = 0;
virtual Base *createCopy() = 0;
};
class Derived1 : public Base
{
public:
Derived1() : Base(){};
virtual void fun() { /* impl */ };
Base *createCopy() override {
return new Derived1();
};
};
class Derived2 : public Base
{
public:
Derived2() : Base(){};
virtual void fun() { /* impl */ };
Base *createCopy() override {
return new Derived2();
};
};
/* Derived3 - Derived8999 implementation*/
class Derived9000 : public Base
{
public:
Derived9000() : Base(){};
virtual void fun() { /* impl */ };
Base *createCopy() override {
return new Derived9000();
};
};
int main()
{
Base *pObj = new Derived9000; // pObj type is Derived9000*
Base *pCopy = pObj->createCopy(); // pCopy type is Derived9000*
}