克隆抽象基类(不干涉派生)

Wal*_*pek 0 c++ abstract-class clone copy

我遇到了一个具有挑战性的问题,这个问题一直无法解决 - 希望到现在为止.我正在开发自己的框架,因此试图为用户提供所有代码复杂性的灵活性.

首先,我有一个用户可以实现的抽象基类,显然简化了:

class IStateTransit
{
public:
    bool ConnectionPossible(void) = 0;
}

// A user defines their own class like so
class MyStateTransit : public IStateTransit
{
public:
    bool ConnectionPossible(void){ return true; }
}
Run Code Online (Sandbox Code Playgroud)

接下来,我定义一个工厂类.用户可以注册自己的自定义状态传输对象,稍后通过使用他们选择的字符串标识符来引用它们:

class TransitFactory : public Singleton<TransitFactory>
{
public:
    template<typename T> void RegisterStateTransit(const string& name)
    {
        // If the transit type is not already registered, add it.
        if(transits.find(name) == transits.end())
        {
            transits.insert(pair<string, IStateTransit*>(name, new T()));
        };
    }

    IStateTransit* TransitFactory::GetStateTransit(const string& type) const
    {
        return transits.find(type)->second;
    };

private:
    map<string, IStateTransit*> transits;
}
Run Code Online (Sandbox Code Playgroud)

现在问题是(可能显然)每当用户通过调用GetStateTransit系统请求传输时,当前一直保持返回相同的对象 - 指向同一对象的指针.我想改变这个.

问题:如何在IStateTransit不需要用户定义自己的复制构造函数或虚拟构造函数的情况下返回原始对象的新(克隆).理想情况下,我会以某种方式喜欢GetStateTransit能够将IStateTransit对象转换为它在运行时的派生类型并返回该实例的副本的方法.最大的障碍是我不希望用户必须实现任何额外的(可能是复杂的)方法.

4小时的谷歌搜索和尝试让我无处可去.有答案的人是英雄!

CB *_*ley 5

问题是您没有类型信息来执行克隆,因为您只有一个指向基类类型的指针,并且不知道哪些派生类型已经实现并且可用.

我认为有一个原因是4小时的谷歌搜索没有任何改变.如果您想要IStateTransit可克隆,则必须有一个接口,其中派生类实现者提供某种克隆方法实现.

如果这不是你想听到的,我很抱歉.

但是,实现克隆方法不应该是一个很大的负担.只有类实现者知道如何复制类,给定正确的复制构造函数,可以为叶节点类实现克隆,如下所示:

Base* clone() const
{
    return new MyType(*this);
}
Run Code Online (Sandbox Code Playgroud)

你甚至可以宏观化它; 虽然我不会.