我有基类和许多从 if 派生的类。我想创建对象副本。有没有一种方法可以在指向基类的指针下推导对象的真实类型,而无需在每个派生类中进行dynamic_cast或createCopy的实现?
类似这样的:
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*
}
您可以通过两种方式做到这一点。 您可以将类型存储在中间层中,如下所示:
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*
}
或者在我看来,更好的方法是让复制函数由特定类型重载,然后让每种类型处理其副本:
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*
}