从基类指针中扣除对象的真实类型来创建副本

问题描述 投票:0回答:1

我有基类和许多从 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*
}
c++ derived-class
1个回答
0
投票

您可以通过两种方式做到这一点。 您可以将类型存储在中间层中,如下所示:

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*
}
© www.soinside.com 2019 - 2024. All rights reserved.